1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

For #299, refine code.

This commit is contained in:
winlin 2017-03-25 17:21:39 +08:00
parent 62b7204514
commit f32aab3d92
175 changed files with 15529 additions and 15935 deletions

View file

@ -1,10 +1,10 @@
/* /*
# see: https://github.com/ossrs/srs/issues/190 # see: https://github.com/ossrs/srs/issues/190
# see: https://github.com/ossrs/srs/wiki/v1_CN_SrsLinuxArm # see: https://github.com/ossrs/srs/wiki/v1_CN_SrsLinuxArm
g++ -g -O0 -o jmp_sp jmp_sp.cpp g++ -g -O0 -o jmp_sp jmp_sp.cpp
arm-linux-gnueabi-g++ -g -o jmp_sp jmp_sp.cpp -static arm-linux-gnueabi-g++ -g -o jmp_sp jmp_sp.cpp -static
arm-linux-gnueabi-strip jmp_sp arm-linux-gnueabi-strip jmp_sp
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <setjmp.h> #include <setjmp.h>
@ -14,14 +14,14 @@ jmp_buf context;
void do_longjmp() void do_longjmp()
{ {
/** /**
the definition of jmp_buf: the definition of jmp_buf:
typedef struct __jmp_buf_tag jmp_buf[1]; typedef struct __jmp_buf_tag jmp_buf[1];
struct __jmp_buf_tag { struct __jmp_buf_tag {
__jmp_buf __jmpbuf; __jmp_buf __jmpbuf;
int __mask_was_saved; int __mask_was_saved;
__sigset_t __saved_mask; __sigset_t __saved_mask;
}; };
*/ */
#if defined(__amd64__) || defined(__x86_64__) #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.2.tar.xz
// http://ftp.gnu.org/gnu/glibc/glibc-2.12.1.tar.gz // 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 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: for example, the following is show the jmp_buf when setjmp:
(gdb) x /64xb context[0].__jmpbuf (gdb) x /64xb context[0].__jmpbuf
0x600ca0 <context>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x600ca0 <context>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x600ca8 <context+8>: 0xf8 0xc1 0x71 0xe5 0xa8 0x88 0xb4 0x15 0x600ca8 <context+8>: 0xf8 0xc1 0x71 0xe5 0xa8 0x88 0xb4 0x15
0x600cb0 <context+16>: 0xa0 0x05 0x40 0x00 0x00 0x00 0x00 0x00 0x600cb0 <context+16>: 0xa0 0x05 0x40 0x00 0x00 0x00 0x00 0x00
0x600cb8 <context+24>: 0x90 0xe4 0xff 0xff 0xff 0x7f 0x00 0x00 0x600cb8 <context+24>: 0x90 0xe4 0xff 0xff 0xff 0x7f 0x00 0x00
0x600cc0 <context+32>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x600cc0 <context+32>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x600cc8 <context+40>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x600cc8 <context+40>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x600cd0 <context+48>: 0xf8 0xc1 0x51 0xe5 0xa8 0x88 0xb4 0x15 0x600cd0 <context+48>: 0xf8 0xc1 0x51 0xe5 0xa8 0x88 0xb4 0x15
0x600cd8 <context+56>: 0xf8 0xc1 0xd9 0x2f 0xd7 0x77 0x4b 0xea 0x600cd8 <context+56>: 0xf8 0xc1 0xd9 0x2f 0xd7 0x77 0x4b 0xea
(gdb) p /x $sp (gdb) p /x $sp
$4 = 0x7fffffffe380 $4 = 0x7fffffffe380
we cannot finger the sp out. we cannot finger the sp out.
where the glibc is 2.12. where the glibc is 2.12.
*/ */
register long int rsp0 asm("rsp"); register long int rsp0 asm("rsp");
int ret = setjmp(context); int ret = setjmp(context);
@ -64,46 +64,46 @@ void do_longjmp()
} }
printf("\n"); printf("\n");
#endif #endif
#if defined(__arm__) #if defined(__arm__)
/** /**
/usr/arm-linux-gnueabi/include/bits/setjmp.h /usr/arm-linux-gnueabi/include/bits/setjmp.h
#ifndef _ASM #ifndef _ASM
The exact set of registers saved may depend on the particular core 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 in use, as some coprocessor registers may need to be saved. The C
Library ABI requires that the buffer be 8-byte aligned, and Library ABI requires that the buffer be 8-byte aligned, and
recommends that the buffer contain 64 words. The first 28 words 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 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.) that d8-15 require 17 words, due to the use of fstmx.)
typedef int __jmp_buf[64] __attribute__((__aligned__ (8))); typedef int __jmp_buf[64] __attribute__((__aligned__ (8)));
the layout of setjmp for arm: the layout of setjmp for arm:
0-5: v1-v6 0-5: v1-v6
6: sl 6: sl
7: fp 7: fp
8: sp 8: sp
9: pc 9: pc
10-26: d8-d15 17words 10-26: d8-d15 17words
27: fpscr 27: fpscr
*/ */
/** /**
For example, on raspberry-pi, armv6 cpu: For example, on raspberry-pi, armv6 cpu:
(gdb) x /64xb (char*)context[0].__jmpbuf (gdb) x /64xb (char*)context[0].__jmpbuf
v1, 0: 0x00 0x00 0x00 0x00 v1, 0: 0x00 0x00 0x00 0x00
v2, 1: 0x00 0x00 0x00 0x00 v2, 1: 0x00 0x00 0x00 0x00
v3, 2: 0x2c 0x84 0x00 0x00 v3, 2: 0x2c 0x84 0x00 0x00
v4, 3: 0x00 0x00 0x00 0x00 v4, 3: 0x00 0x00 0x00 0x00
v5, 4: 0x00 0x00 0x00 0x00 v5, 4: 0x00 0x00 0x00 0x00
v6, 5: 0x00 0x00 0x00 0x00 v6, 5: 0x00 0x00 0x00 0x00
sl, 6: 0x00 0xf0 0xff 0xb6 sl, 6: 0x00 0xf0 0xff 0xb6
fp, 7: 0x9c 0xfb 0xff 0xbe fp, 7: 0x9c 0xfb 0xff 0xbe
sp, 8: 0x88 0xfb 0xff 0xbe sp, 8: 0x88 0xfb 0xff 0xbe
pc, 9: 0x08 0x85 0x00 0x00 pc, 9: 0x08 0x85 0x00 0x00
(gdb) p /x $sp (gdb) p /x $sp
$5 = 0xbefffb88 $5 = 0xbefffb88
(gdb) p /x $pc (gdb) p /x $pc
$4 = 0x850c $4 = 0x850c
*/ */
int ret = setjmp(context); int ret = setjmp(context);
printf("setjmp func1 ret=%d\n", ret); printf("setjmp func1 ret=%d\n", ret);
@ -116,23 +116,23 @@ void do_longjmp()
#endif #endif
} }
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
#if defined(__amd64__) || defined(__x86_64__) #if defined(__amd64__) || defined(__x86_64__)
printf("x86_64 sizeof(long int)=%d, sizeof(long)=%d, " printf("x86_64 sizeof(long int)=%d, sizeof(long)=%d, "
"sizeof(int)=%d, __WORDSIZE=%d, __GLIBC__=%d, __GLIBC_MINOR__=%d\n", "sizeof(int)=%d, __WORDSIZE=%d, __GLIBC__=%d, __GLIBC_MINOR__=%d\n",
(int)sizeof(long int), (int)sizeof(long), (int)sizeof(int), (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int),
(int)__WORDSIZE, (int)__GLIBC__, (int)__GLIBC_MINOR__); (int)__WORDSIZE, (int)__GLIBC__, (int)__GLIBC_MINOR__);
#else #else
printf("arm sizeof(long int)=%d, sizeof(long)=%d, " printf("arm sizeof(long int)=%d, sizeof(long)=%d, "
"sizeof(int)=%d, __GLIBC__=%d,__GLIBC_MINOR__=%d\n", "sizeof(int)=%d, __GLIBC__=%d,__GLIBC_MINOR__=%d\n",
(int)sizeof(long int), (int)sizeof(long), (int)sizeof(int), (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int),
(int)__GLIBC__, (int)__GLIBC_MINOR__); (int)__GLIBC__, (int)__GLIBC_MINOR__);
#endif #endif
do_longjmp(); do_longjmp();
printf("terminated\n"); printf("terminated\n");
return 0; return 0;
} }

View file

@ -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 <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>

View file

@ -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 <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>

View file

@ -29,11 +29,11 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include "../../objs/include/srs_librtmp.h" #include "../../objs/include/srs_librtmp.h"
// https://github.com/ossrs/srs/issues/212#issuecomment-64145910 // 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; 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 // @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 // for instance, frame = FF F1 5C 80 13 A0 FC 00 D0 33 83 E8 5B
*frame = p; *frame = p;
// skip some data. // skip some data.
// @remark, user donot need to do this. // @remark, user donot need to do this.
p += srs_aac_adts_frame_size(p, size - (p - data)); 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); lseek(raw_fd, 0, SEEK_SET);
ssize_t nb_read = 0; ssize_t nb_read = 0;
if ((nb_read = read(raw_fd, audio_raw, file_size)) != file_size) { 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)); raw_file, (int)(file_size / 1024), (int)(nb_read / 1024));
goto rtmp_destroy; goto rtmp_destroy;
} }
@ -164,15 +164,12 @@ int main(int argc, char** argv)
timestamp += time_delta; timestamp += time_delta;
int ret = 0; int ret = 0;
if ((ret = srs_audio_write_raw_frame(rtmp, if ((ret = srs_audio_write_raw_frame(rtmp, sound_format, sound_rate, sound_size, sound_type, data, size, timestamp)) != 0) {
sound_format, sound_rate, sound_size, sound_type,
data, size, timestamp)) != 0
) {
srs_human_trace("send audio raw data failed. ret=%d", ret); srs_human_trace("send audio raw data failed. ret=%d", ret);
goto rtmp_destroy; 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, srs_human_flv_tag_type2string(SRS_RTMP_TYPE_AUDIO), timestamp, size, sound_format, sound_rate, sound_size,
sound_type); sound_type);

View file

@ -29,22 +29,21 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include "../../objs/include/srs_librtmp.h" #include "../../objs/include/srs_librtmp.h"
// https://github.com/ossrs/srs/issues/212#issuecomment-63648892 // https://github.com/ossrs/srs/issues/212#issuecomment-63648892
// allspace: // allspace:
// Take this file as an example: https://github.com/allspace/files/blob/master/srs.pcm // 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. // 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. // 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; char* p = *pp;
if (file_size - (p - audio_raw) < 168) { if (file_size - (p - audio_raw) < 168) {
srs_human_trace("audio must be 160+8 bytes. left %d bytes.", srs_human_trace("audio must be 160+8 bytes. left %d bytes.", (int)(file_size - (p - audio_raw)));
(int)(file_size - (p - audio_raw)));
return - 1; return - 1;
} }
@ -105,7 +104,7 @@ int main(int argc, char** argv)
lseek(raw_fd, 0, SEEK_SET); lseek(raw_fd, 0, SEEK_SET);
ssize_t nb_read = 0; ssize_t nb_read = 0;
if ((nb_read = read(raw_fd, audio_raw, file_size)) != file_size) { 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)); raw_file, (int)(file_size / 1024), (int)(nb_read / 1024));
goto rtmp_destroy; goto rtmp_destroy;
} }
@ -161,15 +160,12 @@ int main(int argc, char** argv)
timestamp += time_delta; timestamp += time_delta;
if (srs_audio_write_raw_frame(rtmp, if (srs_audio_write_raw_frame(rtmp, sound_format, sound_rate, sound_size, sound_type, data, size, timestamp) != 0) {
sound_format, sound_rate, sound_size, sound_type,
data, size, timestamp) != 0
) {
srs_human_trace("send audio raw data failed."); srs_human_trace("send audio raw data failed.");
goto rtmp_destroy; 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, srs_human_flv_tag_type2string(SRS_RTMP_TYPE_AUDIO), timestamp, size, sound_format, sound_rate, sound_size,
sound_type); sound_type);

View file

@ -71,8 +71,8 @@ int do_check(srs_rtmp_t rtmp)
} }
if ((ret = srs_rtmp_bandwidth_check(rtmp, if ((ret = srs_rtmp_bandwidth_check(rtmp,
&start_time, &end_time, &play_kbps, &publish_kbps, &start_time, &end_time, &play_kbps, &publish_kbps, &play_bytes, &publish_bytes,
&play_bytes, &publish_bytes, &play_duration, &publish_duration)) != 0 &play_duration, &publish_duration)) != 0
) { ) {
srs_human_trace("bandwidth check/test failed."); srs_human_trace("bandwidth check/test failed.");
return ret; return ret;
@ -120,7 +120,7 @@ int main(int argc, char** argv)
(char*)sig, NULL, NULL, (char*)sig, NULL, NULL,
(char*)ip, major, minor, revision, build, pid, cid, (char*)ip, major, minor, revision, build, pid, cid,
(int)(end_time - start_time), play_duration, publish_duration, (int)(end_time - start_time), play_duration, publish_duration,
play_kbps, play_kbps,
publish_kbps); publish_kbps);
rtmp_destroy: rtmp_destroy:

View file

@ -56,32 +56,32 @@ int main(int argc, char** argv)
int duration = 0; int duration = 0;
int timeout = 0; int timeout = 0;
enum srs_url_schema sus; enum srs_url_schema sus;
printf("detect rtmp stream\n"); printf("detect rtmp stream\n");
printf("srs(ossrs) client librtmp library.\n"); printf("srs(ossrs) client librtmp library.\n");
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
if (argc <= 3) { if (argc <= 3) {
printf("detect stream on RTMP server, print result to stderr.\n" printf("detect stream on RTMP server, print result to stderr.\n"
"Usage: %s <rtmp_url> <duration> <timeout> [url_schema]\n" "Usage: %s <rtmp_url> <duration> <timeout> [url_schema]\n"
" rtmp_url RTMP stream url to play\n" " rtmp_url RTMP stream url to play\n"
" duration how long to play, in seconds, stream time.\n" " duration how long to play, in seconds, stream time.\n"
" timeout how long to timeout, in seconds, system time.\n" " timeout how long to timeout, in seconds, system time.\n"
" url_schema the schema of url, default to vis, can be:\n" " url_schema the schema of url, default to vis, can be:\n"
" normal: rtmp://vhost:port/app/stream\n" " normal: rtmp://vhost:port/app/stream\n"
" via : rtmp://ip:port/vhost/app/stream\n" " via : rtmp://ip:port/vhost/app/stream\n"
" vis : rtmp://ip:port/app/stream?vhost=xxx\n" " vis : rtmp://ip:port/app/stream?vhost=xxx\n"
" vis2 : rtmp://ip:port/app/stream?domain=xxx\n" " vis2 : rtmp://ip:port/app/stream?domain=xxx\n"
"For example:\n" "For example:\n"
" %s rtmp://127.0.0.1:1935/bravo.chnvideo.com/live/livestream 3 10\n", " %s rtmp://127.0.0.1:1935/bravo.chnvideo.com/live/livestream 3 10\n",
argv[0], argv[0]); argv[0], argv[0]);
exit(-1); exit(-1);
} }
rtmp_url = argv[1]; rtmp_url = argv[1];
duration = atoi(argv[2]); duration = atoi(argv[2]);
timeout = atoi(argv[3]); timeout = atoi(argv[3]);
if (1) { if (1) {
char *p = "vis"; char *p = "vis";
if (argc > 4) { if (argc > 4) {
@ -102,7 +102,7 @@ int main(int argc, char** argv)
} }
srs_human_trace("url schema: %s", p); srs_human_trace("url schema: %s", p);
} }
srs_human_trace("rtmp url: %s", rtmp_url); srs_human_trace("rtmp url: %s", rtmp_url);
srs_human_trace("duration: %ds, timeout:%ds", duration, timeout); 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); srs_human_trace("set url schema=%d failed, ret=%d", sus, ret);
goto rtmp_destroy; goto rtmp_destroy;
} }
if ((ret = srs_rtmp_connect_app(rtmp)) != 0) { if ((ret = srs_rtmp_connect_app(rtmp)) != 0) {
srs_human_trace("connect vhost/app failed. ret=%d", ret); srs_human_trace("connect vhost/app failed. ret=%d", ret);
goto rtmp_destroy; goto rtmp_destroy;
@ -164,8 +164,7 @@ int main(int argc, char** argv)
srs_human_trace("read packet failed. ret=%d", ret); srs_human_trace("read packet failed. ret=%d", ret);
goto rtmp_destroy; goto rtmp_destroy;
} }
srs_human_trace("got packet: type=%s, time=%d, size=%d", srs_human_trace("got packet: type=%s, time=%d, size=%d", srs_human_flv_tag_type2string(type), timestamp, size);
srs_human_flv_tag_type2string(type), timestamp, size);
if (SRS_RTMP_TYPE_VIDEO == type || SRS_RTMP_TYPE_AUDIO == type) { if (SRS_RTMP_TYPE_VIDEO == type || SRS_RTMP_TYPE_AUDIO == type) {
if (time_first_packet <= 0) { if (time_first_packet <= 0) {
@ -231,7 +230,7 @@ rtmp_destroy:
"\"remark0\": \"total = dns + tcp_connect + start_play + first_packet + last_packet\"", "\"remark0\": \"total = dns + tcp_connect + start_play + first_packet + last_packet\"",
"\"remark1\": \"delay = stream - (time_cleanup - time_first_packet)\"", "\"remark1\": \"delay = stream - (time_cleanup - time_first_packet)\"",
"\"remark2\": \"if code is not 0, user must ignore all data\"" "\"remark2\": \"if code is not 0, user must ignore all data\""
); );
srs_human_trace(" "); srs_human_trace(" ");
srs_human_trace("completed"); srs_human_trace("completed");

View file

@ -52,7 +52,7 @@ int main(int argc, char** argv)
// temp variables. // temp variables.
int tmp_file_size = 0; int tmp_file_size = 0;
char* tmp_file; char* tmp_file;
printf("inject flv file keyframes to metadata.\n"); printf("inject flv file keyframes to metadata.\n");
printf("srs(ossrs) client librtmp library.\n"); printf("srs(ossrs) client librtmp library.\n");
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); 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("input: %s", in_flv_file);
srs_human_trace("output: %s", out_flv_file); srs_human_trace("output: %s", out_flv_file);
srs_human_trace("tmp_file: %s", tmp_file); srs_human_trace("tmp_file: %s", tmp_file);
ret = process(in_flv_file, tmp_file, &ic, &oc); ret = process(in_flv_file, tmp_file, &ic, &oc);
srs_flv_close(ic); 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; *poc = oc;
/** /**
* we use two roundtrip to avoid the paddings of metadata, * we use two roundtrip to avoid the paddings of metadata,
* to support large keyframes videos without padding fields. * to support large keyframes videos without padding fields.
*/ */
// build keyframes offset to metadata. // build keyframes offset to metadata.
if ((ret = build_keyframes(ic, &amf0_name, &amf0_data, &filepositions, &metadata_end_offset)) != 0) { if ((ret = build_keyframes(ic, &amf0_name, &amf0_data, &filepositions, &metadata_end_offset)) != 0) {
return ret; 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) { if (amf0_name != NULL && amf0_data != NULL) {
amf0_name_size = srs_amf0_size(amf0_name); amf0_name_size = srs_amf0_size(amf0_name);
size = amf0_name_size + srs_amf0_size(amf0_data); size = amf0_name_size + srs_amf0_size(amf0_data);
// adjust all offset of keyframes. // adjust all offset of keyframes.
new_metadata_end_offset = srs_flv_tellg(oc) + srs_flv_size_tag(size); 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. // the adjust is new offset sub the old offset of metadata end.

View file

@ -59,7 +59,7 @@ int main(int argc, char** argv)
in_flv_file = argv[1]; in_flv_file = argv[1];
srs_human_trace("input: %s", in_flv_file); srs_human_trace("input: %s", in_flv_file);
if ((flv = srs_flv_open_read(in_flv_file)) == NULL) { if ((flv = srs_flv_open_read(in_flv_file)) == NULL) {
ret = 2; ret = 2;
srs_human_trace("open flv file failed. ret=%d", ret); 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(hbuf, 0, hsize);
memset(tbuf, 0, tsize); memset(tbuf, 0, tsize);
if (size > 0) { if (size > 0) {
digit_to_char(data, size, hbuf, hsize - 1); 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) { if (size > print_size * 2) {
digit_to_char(data + size - print_size, size, tbuf, tsize - 1); digit_to_char(data + size - print_size, size, tbuf, tsize - 1);
} }
return 0; return 0;
} }
@ -168,8 +168,7 @@ int parse_flv(srs_flv_t flv)
char hbuf[48]; char tbuf[48]; char hbuf[48]; char tbuf[48];
parse_bytes(data, size, hbuf, sizeof(hbuf), tbuf, sizeof(tbuf), 16); parse_bytes(data, size, hbuf, sizeof(hbuf), tbuf, sizeof(tbuf), 16);
srs_human_raw("offset=%d, first and last 16 bytes:\n" srs_human_raw("offset=%d, first and last 16 bytes:\n[+00, +15] %s\n[-15, EOF] %s\n", (int)offset, hbuf, tbuf);
"[+00, +15] %s\n[-15, EOF] %s\n", (int)offset, hbuf, tbuf);
} else { } else {
srs_human_trace("print packet failed. ret=%d", ret); srs_human_trace("print packet failed. ret=%d", ret);
} }

View file

@ -29,11 +29,11 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include "../../objs/include/srs_librtmp.h" #include "../../objs/include/srs_librtmp.h"
int read_h264_frame(char* data, int size, char** pp, int* pnb_start_code, int fps, 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; 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 // @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) // for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40)
*frame = p; *frame = p;
p += *pnb_start_code; 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. // while the dts and pts must read from encode lib or device.
*dts += 1000 / fps; *dts += 1000 / fps;
*pts = *dts; *pts = *dts;
return 0; return 0;
} }
@ -121,8 +121,8 @@ int main(int argc, char** argv)
lseek(raw_fd, 0, SEEK_SET); lseek(raw_fd, 0, SEEK_SET);
ssize_t nb_read = 0; ssize_t nb_read = 0;
if ((nb_read = read(raw_fd, h264_raw, file_size)) != file_size) { if ((nb_read = read(raw_fd, h264_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)); raw_file, (int)(file_size / 1024), (int)(nb_read / 1024));
goto rtmp_destroy; goto rtmp_destroy;
} }

View file

@ -1,25 +1,25 @@
/* /*
The MIT License (MIT) 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 Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -107,7 +107,7 @@ int main(int argc, char** argv)
srs_human_trace("input: %s", in_flv_file); srs_human_trace("input: %s", in_flv_file);
srs_human_trace("output: %s", out_rtmp_url); srs_human_trace("output: %s", out_rtmp_url);
if ((flv = srs_flv_open_read(in_flv_file)) == NULL) { if ((flv = srs_flv_open_read(in_flv_file)) == NULL) {
ret = 2; ret = 2;
srs_human_trace("open flv file failed. ret=%d", ret); 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); ortmp = srs_rtmp_create(out_rtmp_url);
ret = proxy(flv, ortmp); ret = proxy(flv, ortmp);
srs_human_trace("ingest flv to RTMP completed"); 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); srs_human_trace("irtmp get packet failed. ret=%d", ret);
return ret; return ret;
} }
if (*pstarttime < 0 && srs_utils_flv_tag_is_av(type)) { if (*pstarttime < 0 && srs_utils_flv_tag_is_av(type)) {
*pstarttime = *ptimestamp; *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 now = srs_utils_time_ms();
int64_t diff = time - starttime - (now -re); int64_t diff = time - starttime - (now -re);
if (diff > 0) { if (diff > 0) {
srs_human_trace("re_cleanup, diff=%d, start=%d, last=%d ms", srs_human_trace("re_cleanup, diff=%d, start=%d, last=%d ms", (int)diff, starttime, time);
(int)diff, starttime, time);
usleep((useconds_t)(diff * 1000)); usleep((useconds_t)(diff * 1000));
} }
} }

View file

@ -39,13 +39,13 @@ int main(int argc, char** argv)
if (argc <= 2) { if (argc <= 2) {
printf("Ingest mp4 file and publish to RTMP server\n" printf("Ingest mp4 file and publish to RTMP server\n"
"Usage: %s <-i in_mp4_file> <-y out_rtmp_url>\n" "Usage: %s <-i in_mp4_file> <-y out_rtmp_url>\n"
" in_mp4_file input mp4 file, ingest from this file.\n" " in_mp4_file input mp4 file, ingest from this file.\n"
" out_rtmp_url output rtmp url, publish to this url.\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" "@remark Only support non-seek mp4, see https://github.com/ossrs/srs/issues/738#issuecomment-276343669\n"
"For example:\n" "For example:\n"
" %s -i avatar.mp4 -y rtmp://127.0.0.1/live/livestream\n", " %s -i avatar.mp4 -y rtmp://127.0.0.1/live/livestream\n",
argv[0], argv[0]); argv[0], argv[0]);
exit(-1); exit(-1);
} }

View file

@ -49,7 +49,7 @@ int main(int argc, char** argv)
srs_rtmp_t irtmp, ortmp; srs_rtmp_t irtmp, ortmp;
printf("Ingest RTMP to server like FFMPEG over srs-librtmp %d.%d.%d\n", 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) { if (argc <= 2) {
printf("ingest RTMP and publish to RTMP server\n" 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" " in_rtmp_url input rtmp url, ingest from this url.\n"
" out_rtmp_url output rtmp url, publish to this url.\n" " out_rtmp_url output rtmp url, publish to this url.\n"
" verbose output verbose log.\n" " verbose output verbose log.\n"
"For example:\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\n"
" %s -i rtmp://127.0.0.1/live/livestream -y rtmp://127.0.0.1/live/demo -v verbose\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]); argv[0], argv[0], argv[0]);
exit(-1); exit(-1);
} }
@ -96,7 +96,7 @@ int main(int argc, char** argv)
irtmp = srs_rtmp_create(in_rtmp_url); irtmp = srs_rtmp_create(in_rtmp_url);
ortmp = srs_rtmp_create(out_rtmp_url); ortmp = srs_rtmp_create(out_rtmp_url);
ret = proxy(irtmp, ortmp); ret = proxy(irtmp, ortmp);
srs_human_trace("proxy completed"); srs_human_trace("proxy completed");
@ -116,7 +116,7 @@ int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp)
char* data; char* data;
uint32_t timestamp; uint32_t timestamp;
uint64_t nb_msgs = 0; uint64_t nb_msgs = 0;
if ((ret = connect_ic(irtmp)) != 0) { if ((ret = connect_ic(irtmp)) != 0) {
return ret; return ret;
} }
@ -162,10 +162,10 @@ int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp)
if (verbose) { if (verbose) {
srs_human_trace("ortmp sent packet: type=%s, time=%d, size=%d", 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 { } else {
srs_human_verbose("ortmp sent packet: type=%s, time=%d, size=%d", 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; return ret;
} }
srs_human_trace("irtmp connect ok, ip=%s, server=%s/%d.%d.%d.%d, pid=%d, cid=%d", 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) { if ((ret = srs_rtmp_play_stream(irtmp)) != 0) {
srs_human_trace("irtmp play stream failed. ret=%d", ret); srs_human_trace("irtmp play stream failed. ret=%d", ret);
@ -263,7 +263,7 @@ int connect_oc(srs_rtmp_t ortmp)
return ret; return ret;
} }
srs_human_trace("ortmp connect ok, ip=%s, server=%s/%d.%d.%d.%d, pid=%d, cid=%d", 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) { if ((ret = srs_rtmp_publish_stream(ortmp)) != 0) {
srs_human_trace("ortmp publish stream failed. ret=%d", ret); srs_human_trace("ortmp publish stream failed. ret=%d", ret);

View file

@ -44,7 +44,7 @@ int main(int argc, char** argv)
// warn it . // warn it .
// @see: https://github.com/ossrs/srs/issues/126 // @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. " "[warning] it's only a sample to use librtmp. "
"please never use it to publish and test forward/transcode/edge/HLS whatever. " "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." "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) { if (srs_rtmp_write_packet(rtmp, type, timestamp, data, size) != 0) {
goto rtmp_destroy; goto rtmp_destroy;
} }
srs_human_trace("sent packet: type=%s, time=%d, size=%d", srs_human_trace("sent packet: type=%s, time=%d, size=%d", srs_human_flv_tag_type2string(type), timestamp, size);
srs_human_flv_tag_type2string(type), timestamp, size);
usleep(40 * 1000); usleep(40 * 1000);
} }

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_async_call.hpp> #include <srs_app_async_call.hpp>
@ -48,24 +48,24 @@ SrsAsyncCallWorker::SrsAsyncCallWorker()
SrsAsyncCallWorker::~SrsAsyncCallWorker() SrsAsyncCallWorker::~SrsAsyncCallWorker()
{ {
srs_freep(pthread); srs_freep(pthread);
std::vector<ISrsAsyncCallTask*>::iterator it; std::vector<ISrsAsyncCallTask*>::iterator it;
for (it = tasks.begin(); it != tasks.end(); ++it) { for (it = tasks.begin(); it != tasks.end(); ++it) {
ISrsAsyncCallTask* task = *it; ISrsAsyncCallTask* task = *it;
srs_freep(task); srs_freep(task);
} }
tasks.clear(); tasks.clear();
st_cond_destroy(wait); st_cond_destroy(wait);
} }
int SrsAsyncCallWorker::execute(ISrsAsyncCallTask* t) int SrsAsyncCallWorker::execute(ISrsAsyncCallTask* t)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
tasks.push_back(t); tasks.push_back(t);
st_cond_signal(wait); st_cond_signal(wait);
return ret; return ret;
} }
@ -88,15 +88,15 @@ void SrsAsyncCallWorker::stop()
int SrsAsyncCallWorker::cycle() int SrsAsyncCallWorker::cycle()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
while (pthread->can_loop()) { while (pthread->can_loop()) {
if (tasks.empty()) { if (tasks.empty()) {
st_cond_wait(wait); st_cond_wait(wait);
} }
std::vector<ISrsAsyncCallTask*> copies = tasks; std::vector<ISrsAsyncCallTask*> copies = tasks;
tasks.clear(); tasks.clear();
std::vector<ISrsAsyncCallTask*>::iterator it; std::vector<ISrsAsyncCallTask*>::iterator it;
for (it = copies.begin(); it != copies.end(); ++it) { for (it = copies.begin(); it != copies.end(); ++it) {
ISrsAsyncCallTask* task = *it; ISrsAsyncCallTask* task = *it;
@ -106,7 +106,7 @@ int SrsAsyncCallWorker::cycle()
srs_freep(task); srs_freep(task);
} }
} }
return ret; return ret;
} }

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_ASYNC_CALL_HPP #ifndef SRS_APP_ASYNC_CALL_HPP
#define SRS_APP_ASYNC_CALL_HPP #define SRS_APP_ASYNC_CALL_HPP
/*
#include <srs_app_async_call.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>

View file

@ -1,26 +1,25 @@
/* /**
The MIT License (MIT) * The MIT License (MIT)
*
Copyright (c) 2013-2017 SRS(ossrs) * 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
Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in
this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to
the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so,
the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions:
subject to the following conditions: *
* The above copyright notice and this permission notice shall be included in all
The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software.
copies or substantial portions of the Software. *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
*/
#include <srs_app_bandwidth.hpp> #include <srs_app_bandwidth.hpp>
@ -69,8 +68,8 @@ void SrsBandwidthSample::calc_kbps(int _bytes, int _duration)
} }
/** /**
* recv bandwidth helper. * recv bandwidth helper.
*/ */
typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt); typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt);
bool _bandwidth_is_final(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)) { if (!_srs_config->get_bw_check_enabled(_req->vhost)) {
return ret; return ret;
} }
// validate the bandwidth check key // validate the bandwidth check key
std::string key = "key=" + _srs_config->get_bw_check_key(_req->vhost); std::string key = "key=" + _srs_config->get_bw_check_key(_req->vhost);
if (_req->tcUrl.find(key) == std::string::npos) { if (_req->tcUrl.find(key) == std::string::npos) {
ret = ERROR_SYSTEM_BANDWIDTH_KEY; ret = ERROR_SYSTEM_BANDWIDTH_KEY;
srs_error("check the vhost=%s %s failed, tcUrl=%s, ret=%d", srs_error("check the vhost=%s %s failed, tcUrl=%s, ret=%d",
_req->vhost.c_str(), key.c_str(), _req->tcUrl.c_str(), ret); _req->vhost.c_str(), key.c_str(), _req->tcUrl.c_str(), ret);
return 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) { if (last_check_time > 0 && time_now - last_check_time < interval_ms) {
ret = ERROR_SYSTEM_BANDWIDTH_DENIED; ret = ERROR_SYSTEM_BANDWIDTH_DENIED;
srs_trace("reject, " srs_trace("reject, "
"last_check=%"PRId64", now=%"PRId64", interval=%d", "last_check=%"PRId64", now=%"PRId64", interval=%d",
last_check_time, time_now, interval_ms); last_check_time, time_now, interval_ms);
_rtmp->response_connect_reject(_req, "bandcheck rejected"); _rtmp->response_connect_reject(_req, "bandcheck rejected");
return ret; return ret;
} }
@ -175,7 +174,7 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io
// create a limit object. // create a limit object.
SrsKbps kbps; SrsKbps kbps;
kbps.set_io(io_stat, io_stat); kbps.set_io(io_stat, io_stat);
int limit_kbps = _srs_config->get_bw_check_limit_kbps(_req->vhost); int limit_kbps = _srs_config->get_bw_check_limit_kbps(_req->vhost);
SrsKbpsLimit limit(&kbps, limit_kbps); 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 SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsBandwidthSample play_sample; SrsBandwidthSample play_sample;
SrsBandwidthSample publish_sample; SrsBandwidthSample publish_sample;
// timeout for a packet. // timeout for a packet.
_rtmp->set_send_timeout(play_sample.duration_ms * 2); _rtmp->set_send_timeout(play_sample.duration_ms * 2);
_rtmp->set_recv_timeout(publish_sample.duration_ms * 2); _rtmp->set_recv_timeout(publish_sample.duration_ms * 2);
// start test. // start test.
srs_update_system_time_ms(); srs_update_system_time_ms();
int64_t start_time = srs_get_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); srs_info("stop publish test. kbps=%d", publish_sample.kbps);
// stop test. // stop test.
srs_update_system_time_ms(); srs_update_system_time_ms();
int64_t end_time = srs_get_system_time_ms(); int64_t end_time = srs_get_system_time_ms();
srs_trace("bandwidth ok. duartion=%dms(%d+%d), play=%dkbps, publish=%dkbps", srs_trace("bandwidth ok. duartion=%dms(%d+%d), play=%dkbps, publish=%dkbps",
(int)(end_time - start_time), play_sample.actual_duration_ms, (int)(end_time - start_time), play_sample.actual_duration_ms,
publish_sample.actual_duration_ms, play_sample.kbps, publish_sample.actual_duration_ms, play_sample.kbps,
publish_sample.kbps); publish_sample.kbps);
if ((ret = finial(play_sample, publish_sample, start_time, end_time)) != ERROR_SUCCESS) { if ((ret = finial(play_sample, publish_sample, start_time, end_time)) != ERROR_SUCCESS) {
return ret; return ret;
@ -248,7 +247,7 @@ int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit)
st_usleep(_SRS_BANDWIDTH_FINAL_WAIT_MS * 1000); st_usleep(_SRS_BANDWIDTH_FINAL_WAIT_MS * 1000);
srs_info("BW check finished."); srs_info("BW check finished.");
return ret; return ret;
} }
@ -259,18 +258,18 @@ int SrsBandwidth::play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
if (true) { if (true) {
// send start play command to client // send start play command to client
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_start_play(); SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_start_play();
pkt->data->set("limit_kbps", SrsAmf0Any::number(limit->limit_kbps())); pkt->data->set("limit_kbps", SrsAmf0Any::number(limit->limit_kbps()));
pkt->data->set("duration_ms", SrsAmf0Any::number(sample->duration_ms)); pkt->data->set("duration_ms", SrsAmf0Any::number(sample->duration_ms));
pkt->data->set("interval_ms", SrsAmf0Any::number(sample->interval_ms)); pkt->data->set("interval_ms", SrsAmf0Any::number(sample->interval_ms));
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
srs_error("send bandwidth check start play message failed. ret=%d", ret); srs_error("send bandwidth check start play message failed. ret=%d", ret);
return ret; return ret;
} }
} }
srs_info("BW check play begin."); srs_info("BW check play begin.");
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_starting_play)) != ERROR_SUCCESS) { if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_starting_play)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -282,12 +281,12 @@ int SrsBandwidth::play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit) int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// send play data to client // send play data to client
int size = 1024; // TODO: FIXME: magic number int size = 1024; // TODO: FIXME: magic number
char random_data[size]; char random_data[size];
memset(random_data, 'A', size); memset(random_data, 'A', size);
int data_count = 1; int data_count = 1;
srs_update_system_time_ms(); srs_update_system_time_ms();
int64_t starttime = srs_get_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. // TODO: FIXME: use shared ptr message.
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_playing(); SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_playing();
// TODO: FIXME: magic number // TODO: FIXME: magic number
for (int i = 0; i < data_count; ++i) { for (int i = 0; i < data_count; ++i) {
std::stringstream seq; 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())); pkt->data->set(seq.str(), SrsAmf0Any::str(play_data.c_str()));
} }
data_count += 2; data_count += 2;
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
srs_error("send bandwidth check play messages failed. ret=%d", ret); srs_error("send bandwidth check play messages failed. ret=%d", ret);
return ret; return ret;
@ -323,7 +322,7 @@ int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
int SrsBandwidth::play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit*/) int SrsBandwidth::play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit*/)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (true) { if (true) {
// notify client to stop play // notify client to stop play
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_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("interval_ms", SrsAmf0Any::number(sample->interval_ms));
pkt->data->set("duration_delta", SrsAmf0Any::number(sample->actual_duration_ms)); pkt->data->set("duration_delta", SrsAmf0Any::number(sample->actual_duration_ms));
pkt->data->set("bytes_delta", SrsAmf0Any::number(sample->bytes)); pkt->data->set("bytes_delta", SrsAmf0Any::number(sample->bytes));
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
srs_error("send bandwidth check stop play message failed. ret=%d", ret); srs_error("send bandwidth check stop play message failed. ret=%d", ret);
return ret; return ret;
} }
} }
srs_info("BW check stop play bytes."); srs_info("BW check stop play bytes.");
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stopped_play)) != ERROR_SUCCESS) { if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stopped_play)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -351,22 +350,22 @@ int SrsBandwidth::play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit*/)
int SrsBandwidth::publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit) int SrsBandwidth::publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (true) { if (true) {
// notify client to start publish // notify client to start publish
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_start_publish(); SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_start_publish();
pkt->data->set("limit_kbps", SrsAmf0Any::number(limit->limit_kbps())); pkt->data->set("limit_kbps", SrsAmf0Any::number(limit->limit_kbps()));
pkt->data->set("duration_ms", SrsAmf0Any::number(sample->duration_ms)); pkt->data->set("duration_ms", SrsAmf0Any::number(sample->duration_ms));
pkt->data->set("interval_ms", SrsAmf0Any::number(sample->interval_ms)); pkt->data->set("interval_ms", SrsAmf0Any::number(sample->interval_ms));
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
srs_error("send bandwidth check start publish message failed. ret=%d", ret); srs_error("send bandwidth check start publish message failed. ret=%d", ret);
return ret; return ret;
} }
} }
srs_info("BW check publish begin."); srs_info("BW check publish begin.");
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_starting_publish)) != ERROR_SUCCESS) { if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_starting_publish)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -378,7 +377,7 @@ int SrsBandwidth::publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
int SrsBandwidth::publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit) int SrsBandwidth::publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// recv publish msgs until @duration_ms ms // recv publish msgs until @duration_ms ms
srs_update_system_time_ms(); srs_update_system_time_ms();
int64_t starttime = srs_get_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 SrsBandwidth::publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit*/)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (true) { if (true) {
// notify client to stop publish // notify client to stop publish
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_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("interval_ms", SrsAmf0Any::number(sample->interval_ms));
pkt->data->set("duration_delta", SrsAmf0Any::number(sample->actual_duration_ms)); pkt->data->set("duration_delta", SrsAmf0Any::number(sample->actual_duration_ms));
pkt->data->set("bytes_delta", SrsAmf0Any::number(sample->bytes)); pkt->data->set("bytes_delta", SrsAmf0Any::number(sample->bytes));
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
srs_error("send bandwidth check stop publish message failed. ret=%d", ret); srs_error("send bandwidth check stop publish message failed. ret=%d", ret);
return ret; return ret;
} }
} }
srs_info("BW check stop publish bytes."); srs_info("BW check stop publish bytes.");
// expect client to stop publish // 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, // for the flash send call packet to test publish bandwidth,
// there are many many packets in the queue. // there are many many packets in the queue.
// we just ignore the packet and send the bandwidth test data. // 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 SrsBandwidth::finial(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, int64_t start_time, int64_t& end_time)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// send finished msg, // send finished msg,
// flash client will close connection when got this packet, // flash client will close connection when got this packet,
// for the publish queue may contains packets. // 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("publish_bytes", SrsAmf0Any::number(publish_sample.bytes));
pkt->data->set("play_time", SrsAmf0Any::number(play_sample.actual_duration_ms)); pkt->data->set("play_time", SrsAmf0Any::number(play_sample.actual_duration_ms));
pkt->data->set("publish_time", SrsAmf0Any::number(publish_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) { if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
srs_error("send bandwidth check finish message failed. ret=%d", ret); srs_error("send bandwidth check finish message failed. ret=%d", ret);
return ret; return ret;
@ -474,7 +473,7 @@ int SrsBandwidth::finial(SrsBandwidthSample& play_sample, SrsBandwidthSample& pu
} }
srs_info("BW check finished."); srs_info("BW check finished.");
return ret; return ret;
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * The MIT License (MIT)
*
Copyright (c) 2013-2017 SRS(ossrs) * 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
Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in
this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to
the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so,
the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions:
subject to the following conditions: *
* The above copyright notice and this permission notice shall be included in all
The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software.
copies or substantial portions of the Software. *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
*/
#ifndef SRS_APP_BANDWIDTH_HPP #ifndef SRS_APP_BANDWIDTH_HPP
#define SRS_APP_BANDWIDTH_HPP #define SRS_APP_BANDWIDTH_HPP
/*
#include <srs_app_bandwidth.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
@ -41,84 +37,84 @@ class SrsKbpsLimit;
class ISrsProtocolStatistic; class ISrsProtocolStatistic;
/** /**
* bandwidth check/test sample. * bandwidth check/test sample.
*/ */
class SrsBandwidthSample class SrsBandwidthSample
{ {
public: public:
/** /**
* the plan, how long to do the test, in ms, * the plan, how long to do the test, in ms,
* if exceed the duration, abort the test. * if exceed the duration, abort the test.
*/ */
int duration_ms; 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; int interval_ms;
public: public:
/** /**
* the actual test duration, in ms. * the actual test duration, in ms.
*/ */
int actual_duration_ms; int actual_duration_ms;
/** /**
* the actual test bytes * the actual test bytes
*/ */
int bytes; int bytes;
/** /**
* the actual test kbps * the actual test kbps
*/ */
int kbps; int kbps;
public: public:
SrsBandwidthSample(); SrsBandwidthSample();
virtual ~SrsBandwidthSample(); virtual ~SrsBandwidthSample();
public: public:
/** /**
* update the bytes and actual duration, then calc the kbps. * update the bytes and actual duration, then calc the kbps.
* @param _bytes update the sample bytes. * @param _bytes update the sample bytes.
* @param _duration update the actual duration, in ms. * @param _duration update the actual duration, in ms.
*/ */
virtual void calc_kbps(int _bytes, int _duration); virtual void calc_kbps(int _bytes, int _duration);
}; };
/** /**
* bandwidth test agent which provides the interfaces for bandwidth check. * bandwidth test agent which provides the interfaces for bandwidth check.
* 1. if vhost disabled bandwidth check, ignore. * 1. if vhost disabled bandwidth check, ignore.
* 2. otherwise, check the key, error if verify failed. * 2. otherwise, check the key, error if verify failed.
* 3. check the interval limit, error if bandwidth in the interval window. * 3. check the interval limit, error if bandwidth in the interval window.
* 4. check the bandwidth under the max kbps. * 4. check the bandwidth under the max kbps.
* 5. send the bandwidth data to client. * 5. send the bandwidth data to client.
* bandwidth workflow: * bandwidth workflow:
* +------------+ +----------+ * +------------+ +----------+
* | Client | | Server | * | Client | | Server |
* +-----+------+ +-----+----+ * +-----+------+ +-----+----+
* | | * | |
* | connect vhost------> | if vhost enable bandwidth, * | connect vhost------> | if vhost enable bandwidth,
* | <-----result(success) | do bandwidth check. * | <-----result(success) | do bandwidth check.
* | | * | |
* | <----call(start play) | onSrsBandCheckStartPlayBytes * | <----call(start play) | onSrsBandCheckStartPlayBytes
* | result(playing)-----> | onSrsBandCheckStartingPlayBytes * | result(playing)-----> | onSrsBandCheckStartingPlayBytes
* | <-------data(playing) | onSrsBandCheckStartingPlayBytes * | <-------data(playing) | onSrsBandCheckStartingPlayBytes
* | <-----call(stop play) | onSrsBandCheckStopPlayBytes * | <-----call(stop play) | onSrsBandCheckStopPlayBytes
* | result(stopped)-----> | onSrsBandCheckStoppedPlayBytes * | result(stopped)-----> | onSrsBandCheckStoppedPlayBytes
* | | * | |
* | <-call(start publish) | onSrsBandCheckStartPublishBytes * | <-call(start publish) | onSrsBandCheckStartPublishBytes
* | result(publishing)--> | onSrsBandCheckStartingPublishBytes * | result(publishing)--> | onSrsBandCheckStartingPublishBytes
* | data(publishing)(3)-> | onSrsBandCheckStartingPublishBytes * | data(publishing)(3)-> | onSrsBandCheckStartingPublishBytes
* | <--call(stop publish) | onSrsBandCheckStopPublishBytes * | <--call(stop publish) | onSrsBandCheckStopPublishBytes
* | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes * | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes
* | | * | |
* | <--------------report | * | <--------------report |
* | final(2)------------> | finalClientPacket * | final(2)------------> | finalClientPacket
* | <END> | * | <END> |
* *
* 1. when flash client, server never wait the stop publish response, * 1. when flash client, server never wait the stop publish response,
* for the flash client queue is fullfill with other packets. * for the flash client queue is fullfill with other packets.
* 2. when flash client, server never wait the final packet, * 2. when flash client, server never wait the final packet,
* for the flash client directly close when got report 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, * 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. * for the linux client donot know when to stop the publish.
* when server got publishing and stop publish, stop publish. * when server got publishing and stop publish, stop publish.
*/ */
class SrsBandwidth class SrsBandwidth
{ {
private: private:
@ -129,74 +125,74 @@ public:
virtual ~SrsBandwidth(); virtual ~SrsBandwidth();
public: public:
/** /**
* do the bandwidth check. * do the bandwidth check.
* @param rtmp, server RTMP protocol object, send/recv RTMP packet to/from client. * @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 io_stat, the underlayer io statistic, provides send/recv bytes count.
* @param req, client request object, specifies the request info from client. * @param req, client request object, specifies the request info from client.
* @param local_ip, the ip of server which client connected at * @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); virtual int bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io_stat, SrsRequest* req, std::string local_ip);
private: private:
/** /**
* used to process band width check from client. * used to process band width check from client.
* @param limit, the bandwidth limit object, to slowdown if exceed the kbps. * @param limit, the bandwidth limit object, to slowdown if exceed the kbps.
*/ */
virtual int do_bandwidth_check(SrsKbpsLimit* limit); virtual int do_bandwidth_check(SrsKbpsLimit* limit);
// play check/test, downloading bandwidth kbps. // play check/test, downloading bandwidth kbps.
private: private:
/** /**
* start play/download bandwidth check/test, * start play/download bandwidth check/test,
* send start-play command to client, client must response starting-play * send start-play command to client, client must response starting-play
* to start the test. * to start the test.
*/ */
virtual int play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual int play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
/** /**
* do play/download bandwidth check/test, * do play/download bandwidth check/test,
* server send call messages to client in specified time, * server send call messages to client in specified time,
* calc the time and bytes sent, then we got the kbps. * calc the time and bytes sent, then we got the kbps.
*/ */
virtual int play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual int play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
/** /**
* stop play/download bandwidth check/test, * stop play/download bandwidth check/test,
* send stop-play command to client, client must response stopped-play * send stop-play command to client, client must response stopped-play
* to stop the test. * to stop the test.
*/ */
virtual int play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual int play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
// publish check/test, publishing bandwidth kbps. // publish check/test, publishing bandwidth kbps.
private: private:
/** /**
* start publish/upload bandwidth check/test, * start publish/upload bandwidth check/test,
* send start-publish command to client, client must response starting-publish * send start-publish command to client, client must response starting-publish
* to start the test. * to start the test.
*/ */
virtual int publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual int publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
/** /**
* do publish/upload bandwidth check/test, * do publish/upload bandwidth check/test,
* client send call messages to client in specified time, * client send call messages to client in specified time,
* server calc the time and bytes received, then we got the kbps. * 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. * @remark, for linux client, it will send a stop publish client, server will stop publishing.
* then enter the publish-stop stage with client. * then enter the publish-stop stage with client.
* @remark, for flash client, it will send many many call messages, that is, * @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 * the send queue is fullfill with call messages, so we should never expect the
* response message in the publish-stop stage. * response message in the publish-stop stage.
*/ */
virtual int publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual int publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
/** /**
* stop publish/upload bandwidth check/test, * stop publish/upload bandwidth check/test,
* send stop-publish command to client, * send stop-publish command to client,
* for linux client, always expect a stopped-publish response from client, * for linux client, always expect a stopped-publish response from client,
* for flash client, the sent queue is fullfill with publishing call messages, * for flash client, the sent queue is fullfill with publishing call messages,
* so server never expect the stopped-publish from it. * so server never expect the stopped-publish from it.
*/ */
virtual int publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual int publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
private: private:
/** /**
* report and final packet * report and final packet
* report a finish packet, with the bytes/time/kbps bandwidth check/test result, * 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 linux client, server always expect a final packet from client,
* for flash client, the sent queue is fullfill with publishing call messages, * for flash client, the sent queue is fullfill with publishing call messages,
* so server never expect the final packet from it. * 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); virtual int finial(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, int64_t start_time, int64_t& end_time);
}; };

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_caster_flv.hpp> #include <srs_app_caster_flv.hpp>
@ -118,7 +118,7 @@ int SrsAppCasterFlv::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
} }
SrsDynamicHttpConn::SrsDynamicHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m, string cip) SrsDynamicHttpConn::SrsDynamicHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m, string cip)
: SrsHttpConn(cm, fd, m, cip) : SrsHttpConn(cm, fd, m, cip)
{ {
sdk = NULL; sdk = NULL;
pprint = SrsPithyPrint::create_caster(); pprint = SrsPithyPrint::create_caster();

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_CASTER_FLV_HPP #ifndef SRS_APP_CASTER_FLV_HPP
#define SRS_APP_CASTER_FLV_HPP #define SRS_APP_CASTER_FLV_HPP
/*
#include <srs_app_caster_flv.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
@ -56,7 +52,7 @@ class SrsSimpleRtmpClient;
* the stream caster for flv stream over HTTP POST. * the stream caster for flv stream over HTTP POST.
*/ */
class SrsAppCasterFlv : virtual public ISrsTcpHandler class SrsAppCasterFlv : virtual public ISrsTcpHandler
, virtual public IConnectionManager, virtual public ISrsHttpHandler , virtual public IConnectionManager, virtual public ISrsHttpHandler
{ {
private: private:
std::string output; std::string output;
@ -67,13 +63,13 @@ public:
virtual ~SrsAppCasterFlv(); virtual ~SrsAppCasterFlv();
public: public:
virtual int initialize(); virtual int initialize();
// ISrsTcpHandler // ISrsTcpHandler
public: public:
virtual int on_tcp_client(st_netfd_t stfd); virtual int on_tcp_client(st_netfd_t stfd);
// IConnectionManager // IConnectionManager
public: public:
virtual void remove(SrsConnection* c); virtual void remove(SrsConnection* c);
// ISrsHttpHandler // ISrsHttpHandler
public: public:
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
}; };

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_config.hpp> #include <srs_app_config.hpp>
@ -156,8 +156,8 @@ namespace _srs_internal
// read total content from file. // read total content from file.
ssize_t nread = 0; ssize_t nread = 0;
if ((ret = reader.read(start, filesize, &nread)) != ERROR_SUCCESS) { if ((ret = reader.read(start, filesize, &nread)) != ERROR_SUCCESS) {
srs_error("read file read error. expect %d, actual %d bytes, ret=%d", srs_error("read file read error. expect %d, actual %d bytes, ret=%d",
filesize, nread, ret); filesize, nread, ret);
return 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" 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 == "mw_latency" || n == "gop_cache" || n == "queue_length" || n == "send_min_interval"
|| n == "reduce_sequence_header" || n == "reduce_sequence_header"
) { ) {
it = dir->directives.erase(it); it = dir->directives.erase(it);
SrsConfDirective* play = dir->get_or_create("play"); 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 = read_token(buffer, args, line_start);
/** /**
* ret maybe: * ret maybe:
* ERROR_SYSTEM_CONFIG_INVALID error. * ERROR_SYSTEM_CONFIG_INVALID error.
* ERROR_SYSTEM_CONFIG_DIRECTIVE directive terminated by ';' found * ERROR_SYSTEM_CONFIG_DIRECTIVE directive terminated by ';' found
* ERROR_SYSTEM_CONFIG_BLOCK_START token terminated by '{' found * ERROR_SYSTEM_CONFIG_BLOCK_START token terminated by '{' found
* ERROR_SYSTEM_CONFIG_BLOCK_END the '}' found * ERROR_SYSTEM_CONFIG_BLOCK_END the '}' found
* ERROR_SYSTEM_CONFIG_EOF the config file is done * ERROR_SYSTEM_CONFIG_EOF the config file is done
*/ */
if (ret == ERROR_SYSTEM_CONFIG_INVALID) { if (ret == ERROR_SYSTEM_CONFIG_INVALID) {
return ret; return ret;
} }
@ -958,7 +958,7 @@ int SrsConfDirective::parse_conf(SrsConfigBuffer* buffer, SrsDirectiveType type)
// build directive tree. // build directive tree.
SrsConfDirective* directive = new SrsConfDirective(); SrsConfDirective* directive = new SrsConfDirective();
directive->conf_line = line_start; directive->conf_line = line_start;
directive->name = args[0]; directive->name = args[0];
args.erase(args.begin()); args.erase(args.begin());
@ -980,9 +980,9 @@ int SrsConfDirective::parse_conf(SrsConfigBuffer* buffer, SrsDirectiveType type)
int SrsConfDirective::read_token(SrsConfigBuffer* buffer, vector<string>& args, int& line_start) int SrsConfDirective::read_token(SrsConfigBuffer* buffer, vector<string>& args, int& line_start)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
char* pstart = buffer->pos; char* pstart = buffer->pos;
bool sharp_comment = false; bool sharp_comment = false;
bool d_quoted = false; bool d_quoted = false;
@ -1028,7 +1028,7 @@ int SrsConfDirective::read_token(SrsConfigBuffer* buffer, vector<string>& args,
return ERROR_SYSTEM_CONFIG_BLOCK_START; return ERROR_SYSTEM_CONFIG_BLOCK_START;
} }
srs_error("line %d: unexpected '%c'", buffer->line, ch); srs_error("line %d: unexpected '%c'", buffer->line, ch);
return ERROR_SYSTEM_CONFIG_INVALID; return ERROR_SYSTEM_CONFIG_INVALID;
} }
// last charecter is space. // last charecter is space.
@ -1190,9 +1190,9 @@ void SrsConfig::unsubscribe(ISrsReloadHandler* handler)
int SrsConfig::reload() int SrsConfig::reload()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsConfig conf; SrsConfig conf;
if ((ret = conf.parse_file(config_file.c_str())) != ERROR_SUCCESS) { if ((ret = conf.parse_file(config_file.c_str())) != ERROR_SUCCESS) {
srs_error("ignore config reloader parse file failed. ret=%d", ret); srs_error("ignore config reloader parse file failed. ret=%d", ret);
ret = ERROR_SUCCESS; ret = ERROR_SUCCESS;
@ -1205,7 +1205,7 @@ int SrsConfig::reload()
srs_error("transform config failed. ret=%d", ret); srs_error("transform config failed. ret=%d", ret);
return ret; return ret;
} }
if ((ret = conf.check_config()) != ERROR_SUCCESS) { if ((ret = conf.check_config()) != ERROR_SUCCESS) {
srs_error("ignore config reloader check config failed. ret=%d", ret); srs_error("ignore config reloader check config failed. ret=%d", ret);
ret = ERROR_SUCCESS; ret = ERROR_SUCCESS;
@ -1230,7 +1230,7 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root)
// DISABLED => ENABLED // DISABLED => ENABLED
// ENABLED => DISABLED // ENABLED => DISABLED
// ENABLED => ENABLED (modified) // ENABLED => ENABLED (modified)
// collect all vhost names // collect all vhost names
std::vector<std::string> vhosts; std::vector<std::string> vhosts;
for (int i = 0; i < (int)root->directives.size(); i++) { for (int i = 0; i < (int)root->directives.size(); i++) {
@ -1254,7 +1254,7 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root)
// process each vhost // process each vhost
for (int i = 0; i < (int)vhosts.size(); i++) { for (int i = 0; i < (int)vhosts.size(); i++) {
std::string vhost = vhosts.at(i); std::string vhost = vhosts.at(i);
SrsConfDirective* old_vhost = old_root->get("vhost", vhost); SrsConfDirective* old_vhost = old_root->get("vhost", vhost);
SrsConfDirective* new_vhost = 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: // the auto reload configs:
// publish.parse_sps // publish.parse_sps
// ENABLED => ENABLED (modified) // ENABLED => ENABLED (modified)
if (get_vhost_enabled(new_vhost) && get_vhost_enabled(old_vhost)) { if (get_vhost_enabled(new_vhost) && get_vhost_enabled(old_vhost)) {
srs_trace("vhost %s maybe modified, reload its detail.", vhost.c_str()); 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()); srs_trace("vhost %s reload hls success.", vhost.c_str());
} }
// hds reload // hds reload
if (!srs_directive_equals(new_vhost->get("hds"), old_vhost->get("hds"))) { if (!srs_directive_equals(new_vhost->get("hds"), old_vhost->get("hds"))) {
for (it = subscribes.begin(); it != subscribes.end(); ++it) { 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()); srs_trace("vhost %s reload hds success.", vhost.c_str());
} }
// dvr, only one per vhost, except the dvr_apply // dvr, only one per vhost, except the dvr_apply
if (!srs_directive_equals(new_vhost->get("dvr"), old_vhost->get("dvr"), "dvr_apply")) { if (!srs_directive_equals(new_vhost->get("dvr"), old_vhost->get("dvr"), "dvr_apply")) {
for (it = subscribes.begin(); it != subscribes.end(); ++it) { for (it = subscribes.begin(); it != subscribes.end(); ++it) {
@ -1473,9 +1473,9 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root)
continue; continue;
} }
srs_trace("ignore reload vhost, enabled old: %d, new: %d", 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; return ret;
} }
@ -1491,7 +1491,7 @@ int SrsConfig::reload_conf(SrsConfig* conf)
// merge config. // merge config.
std::vector<ISrsReloadHandler*>::iterator it; std::vector<ISrsReloadHandler*>::iterator it;
// never support reload: // never support reload:
// daemon // daemon
// //
@ -1499,7 +1499,7 @@ int SrsConfig::reload_conf(SrsConfig* conf)
// chunk_size, ff_log_dir, // chunk_size, ff_log_dir,
// bandcheck, http_hooks, heartbeat, // bandcheck, http_hooks, heartbeat,
// security // security
// merge config: listen // merge config: listen
if (!srs_directive_equals(root->get("listen"), old_root->get("listen"))) { if (!srs_directive_equals(root->get("listen"), old_root->get("listen"))) {
if ((ret = do_reload_listen()) != ERROR_SUCCESS) { 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) { if ((ret = reload_http_stream(old_root)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// TODO: FIXME: support reload stream_caster. // TODO: FIXME: support reload stream_caster.
// TODO: FIXME: support reload kafka. // TODO: FIXME: support reload kafka.
// merge config: vhost // merge config: vhost
if ((ret = reload_vhost(old_root)) != ERROR_SUCCESS) { if ((ret = reload_vhost(old_root)) != ERROR_SUCCESS) {
return ret; return ret;
@ -1592,7 +1592,7 @@ int SrsConfig::reload_http_api(SrsConfDirective* old_root)
SrsConfDirective* new_http_api = root->get("http_api"); SrsConfDirective* new_http_api = root->get("http_api");
SrsConfDirective* old_http_api = old_root->get("http_api"); SrsConfDirective* old_http_api = old_root->get("http_api");
// DISABLED => ENABLED // DISABLED => ENABLED
if (!get_http_api_enabled(old_http_api) && get_http_api_enabled(new_http_api)) { if (!get_http_api_enabled(old_http_api) && get_http_api_enabled(new_http_api)) {
for (it = subscribes.begin(); it != subscribes.end(); ++it) { for (it = subscribes.begin(); it != subscribes.end(); ++it) {
@ -1606,7 +1606,7 @@ int SrsConfig::reload_http_api(SrsConfDirective* old_root)
return ret; return ret;
} }
// ENABLED => DISABLED // ENABLED => DISABLED
if (get_http_api_enabled(old_http_api) && !get_http_api_enabled(new_http_api)) { if (get_http_api_enabled(old_http_api) && !get_http_api_enabled(new_http_api)) {
for (it = subscribes.begin(); it != subscribes.end(); ++it) { for (it = subscribes.begin(); it != subscribes.end(); ++it) {
@ -1624,7 +1624,7 @@ int SrsConfig::reload_http_api(SrsConfDirective* old_root)
// ENABLED => ENABLED (modified) // ENABLED => ENABLED (modified)
if (get_http_api_enabled(old_http_api) && get_http_api_enabled(new_http_api) if (get_http_api_enabled(old_http_api) && get_http_api_enabled(new_http_api)
&& !srs_directive_equals(old_http_api, new_http_api) && !srs_directive_equals(old_http_api, new_http_api)
) { ) {
for (it = subscribes.begin(); it != subscribes.end(); ++it) { for (it = subscribes.begin(); it != subscribes.end(); ++it) {
ISrsReloadHandler* subscribe = *it; ISrsReloadHandler* subscribe = *it;
if ((ret = subscribe->on_reload_http_api_enabled()) != ERROR_SUCCESS) { 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* new_http_stream = root->get("http_server");
SrsConfDirective* old_http_stream = old_root->get("http_server"); SrsConfDirective* old_http_stream = old_root->get("http_server");
// DISABLED => ENABLED // DISABLED => ENABLED
if (!get_http_stream_enabled(old_http_stream) && get_http_stream_enabled(new_http_stream)) { if (!get_http_stream_enabled(old_http_stream) && get_http_stream_enabled(new_http_stream)) {
for (it = subscribes.begin(); it != subscribes.end(); ++it) { for (it = subscribes.begin(); it != subscribes.end(); ++it) {
@ -1693,7 +1693,7 @@ int SrsConfig::reload_http_stream(SrsConfDirective* old_root)
return ret; return ret;
} }
// ENABLED => DISABLED // ENABLED => DISABLED
if (get_http_stream_enabled(old_http_stream) && !get_http_stream_enabled(new_http_stream)) { if (get_http_stream_enabled(old_http_stream) && !get_http_stream_enabled(new_http_stream)) {
for (it = subscribes.begin(); it != subscribes.end(); ++it) { for (it = subscribes.begin(); it != subscribes.end(); ++it) {
@ -1711,7 +1711,7 @@ int SrsConfig::reload_http_stream(SrsConfDirective* old_root)
// ENABLED => ENABLED (modified) // ENABLED => ENABLED (modified)
if (get_http_stream_enabled(old_http_stream) && get_http_stream_enabled(new_http_stream) if (get_http_stream_enabled(old_http_stream) && get_http_stream_enabled(new_http_stream)
&& !srs_directive_equals(old_http_stream, new_http_stream) && !srs_directive_equals(old_http_stream, new_http_stream)
) { ) {
for (it = subscribes.begin(); it != subscribes.end(); ++it) { for (it = subscribes.begin(); it != subscribes.end(); ++it) {
ISrsReloadHandler* subscribe = *it; ISrsReloadHandler* subscribe = *it;
if ((ret = subscribe->on_reload_http_stream_updated()) != ERROR_SUCCESS) { 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(); std::string vhost = new_vhost->arg0();
// to be simple: // to be simple:
// whatever, once tiny changed of transcode, // whatever, once tiny changed of transcode,
// restart all ffmpeg of vhost. // restart all ffmpeg of vhost.
bool changed = false; bool changed = false;
@ -1860,8 +1860,8 @@ int SrsConfig::reload_ingest(SrsConfDirective* new_vhost, SrsConfDirective* old_
for (it = subscribes.begin(); it != subscribes.end(); ++it) { for (it = subscribes.begin(); it != subscribes.end(); ++it) {
ISrsReloadHandler* subscribe = *it; ISrsReloadHandler* subscribe = *it;
if ((ret = subscribe->on_reload_ingest_removed(vhost, ingest_id)) != ERROR_SUCCESS) { if ((ret = subscribe->on_reload_ingest_removed(vhost, ingest_id)) != ERROR_SUCCESS) {
srs_error("vhost %s notify subscribes ingest=%s removed failed. ret=%d", srs_error("vhost %s notify subscribes ingest=%s removed failed. ret=%d",
vhost.c_str(), ingest_id.c_str(), ret); vhost.c_str(), ingest_id.c_str(), ret);
return ret; return ret;
} }
} }
@ -1880,15 +1880,15 @@ int SrsConfig::reload_ingest(SrsConfDirective* new_vhost, SrsConfDirective* old_
for (it = subscribes.begin(); it != subscribes.end(); ++it) { for (it = subscribes.begin(); it != subscribes.end(); ++it) {
ISrsReloadHandler* subscribe = *it; ISrsReloadHandler* subscribe = *it;
if ((ret = subscribe->on_reload_ingest_added(vhost, ingest_id)) != ERROR_SUCCESS) { if ((ret = subscribe->on_reload_ingest_added(vhost, ingest_id)) != ERROR_SUCCESS) {
srs_error("vhost %s notify subscribes ingest=%s added failed. ret=%d", srs_error("vhost %s notify subscribes ingest=%s added failed. ret=%d",
vhost.c_str(), ingest_id.c_str(), ret); vhost.c_str(), ingest_id.c_str(), ret);
return ret; return ret;
} }
} }
srs_trace("vhost %s reload ingest=%s added success.", vhost.c_str(), ingest_id.c_str()); srs_trace("vhost %s reload ingest=%s added success.", vhost.c_str(), ingest_id.c_str());
} }
} }
// for updated ingesters, restart them. // for updated ingesters, restart them.
for (int i = 0; i < (int)new_ingesters.size(); i++) { for (int i = 0; i < (int)new_ingesters.size(); i++) {
SrsConfDirective* new_ingester = new_ingesters.at(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)) { if (srs_directive_equals(new_ingester, old_ingester)) {
continue; continue;
} }
// notice handler ingester removed. // notice handler ingester removed.
for (it = subscribes.begin(); it != subscribes.end(); ++it) { for (it = subscribes.begin(); it != subscribes.end(); ++it) {
ISrsReloadHandler* subscribe = *it; ISrsReloadHandler* subscribe = *it;
if ((ret = subscribe->on_reload_ingest_updated(vhost, ingest_id)) != ERROR_SUCCESS) { if ((ret = subscribe->on_reload_ingest_updated(vhost, ingest_id)) != ERROR_SUCCESS) {
srs_error("vhost %s notify subscribes ingest=%s updated failed. ret=%d", srs_error("vhost %s notify subscribes ingest=%s updated failed. ret=%d",
vhost.c_str(), ingest_id.c_str(), ret); vhost.c_str(), ingest_id.c_str(), ret);
return ret; return ret;
} }
} }
srs_trace("vhost %s reload ingest=%s updated success.", vhost.c_str(), ingest_id.c_str()); 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()); srs_trace("ingest not changed for vhost=%s", vhost.c_str());
return ret; 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); srs_error("config file not specified, see help: %s -h, ret=%d", argv[0], ret);
return ret; return ret;
} }
ret = parse_file(config_file.c_str()); ret = parse_file(config_file.c_str());
// transform config to compatible with previous style of config. // 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) { if (ret == ERROR_SUCCESS) {
ret = check_config(); ret = check_config();
} }
if (ret == ERROR_SUCCESS) { if (ret == ERROR_SUCCESS) {
srs_trace("config file is ok"); srs_trace("config file is ok");
exit(0); exit(0);
@ -1987,7 +1987,7 @@ int SrsConfig::parse_options(int argc, char** argv)
exit(ret); exit(ret);
} }
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// check log name and level // check log name and level
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -2013,12 +2013,12 @@ int SrsConfig::parse_options(int argc, char** argv)
int SrsConfig::initialize_cwd() int SrsConfig::initialize_cwd()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// cwd // cwd
char cwd[256]; char cwd[256];
getcwd(cwd, sizeof(cwd)); getcwd(cwd, sizeof(cwd));
_cwd = cwd; _cwd = cwd;
return ret; return ret;
} }
@ -3410,7 +3410,7 @@ int SrsConfig::parse_argv(int& i, char** argv)
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
char* p = argv[i]; char* p = argv[i];
if (*p++ != '-') { if (*p++ != '-') {
show_help = true; show_help = true;
return ret; return ret;
@ -3488,33 +3488,33 @@ int SrsConfig::parse_argv(int& i, char** argv)
void SrsConfig::print_help(char** argv) void SrsConfig::print_help(char** argv)
{ {
printf( printf(
RTMP_SIG_SRS_SERVER" "RTMP_SIG_SRS_COPYRIGHT"\n" RTMP_SIG_SRS_SERVER" "RTMP_SIG_SRS_COPYRIGHT"\n"
"License: "RTMP_SIG_SRS_LICENSE"\n" "License: "RTMP_SIG_SRS_LICENSE"\n"
"Primary: "RTMP_SIG_SRS_PRIMARY"\n" "Primary: "RTMP_SIG_SRS_PRIMARY"\n"
"Authors: "RTMP_SIG_SRS_AUTHROS"\n" "Authors: "RTMP_SIG_SRS_AUTHROS"\n"
"Build: "SRS_AUTO_BUILD_DATE" Configuration:"SRS_AUTO_USER_CONFIGURE"\n" "Build: "SRS_AUTO_BUILD_DATE" Configuration:"SRS_AUTO_USER_CONFIGURE"\n"
"Features:"SRS_AUTO_CONFIGURE"\n""\n" "Features:"SRS_AUTO_CONFIGURE"\n""\n"
"Usage: %s [-h?vVsS] [[-t] -c <filename>]\n" "Usage: %s [-h?vVsS] [[-t] -c <filename>]\n"
"\n" "\n"
"Options:\n" "Options:\n"
" -?, -h : show this help and exit(0)\n" " -?, -h : show this help and exit(0)\n"
" -v, -V : show version and exit(0)\n" " -v, -V : show version and exit(0)\n"
" -g, -G : show server signature and exit(0)\n" " -g, -G : show server signature and exit(0)\n"
" -t : test configuration file, exit(error_code).\n" " -t : test configuration file, exit(error_code).\n"
" -c filename : use configuration file for SRS\n" " -c filename : use configuration file for SRS\n"
"For srs-dolphin:\n" "For srs-dolphin:\n"
" -p rtmp-port : the rtmp port to listen.\n" " -p rtmp-port : the rtmp port to listen.\n"
" -x http-port : the http port to listen.\n" " -x http-port : the http port to listen.\n"
"\n" "\n"
RTMP_SIG_SRS_WEB"\n" RTMP_SIG_SRS_WEB"\n"
RTMP_SIG_SRS_URL"\n" RTMP_SIG_SRS_URL"\n"
"Email: "RTMP_SIG_SRS_EMAIL"\n" "Email: "RTMP_SIG_SRS_EMAIL"\n"
"\n" "\n"
"For example:\n" "For example:\n"
" %s -v\n" " %s -v\n"
" %s -t -c "SRS_CONF_DEFAULT_COFNIG_FILE"\n" " %s -t -c "SRS_CONF_DEFAULT_COFNIG_FILE"\n"
" %s -c "SRS_CONF_DEFAULT_COFNIG_FILE"\n", " %s -c "SRS_CONF_DEFAULT_COFNIG_FILE"\n",
argv[0], argv[0], argv[0], argv[0]); argv[0], argv[0], argv[0], argv[0]);
} }
int SrsConfig::parse_file(const char* filename) int SrsConfig::parse_file(const char* filename)
@ -3539,9 +3539,9 @@ int SrsConfig::parse_file(const char* filename)
int SrsConfig::check_config() int SrsConfig::check_config()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
srs_trace("srs checking config..."); srs_trace("srs checking config...");
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// check empty // check empty
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -3557,13 +3557,13 @@ int SrsConfig::check_config()
for (int i = 0; i < (int)root->directives.size(); i++) { for (int i = 0; i < (int)root->directives.size(); i++) {
SrsConfDirective* conf = root->at(i); SrsConfDirective* conf = root->at(i);
std::string n = conf->name; 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 != "srs_log_tank" && n != "srs_log_level" && n != "srs_log_file"
&& n != "max_connections" && n != "daemon" && n != "heartbeat" && n != "max_connections" && n != "daemon" && n != "heartbeat"
&& n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms" && n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms"
&& n != "http_server" && n != "stream_caster" && n != "kafka" && n != "http_server" && n != "stream_caster" && n != "kafka"
&& n != "utc_time" && n != "work_dir" && n != "asprocess" && n != "utc_time" && n != "work_dir" && n != "asprocess"
) { ) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("unsupported directive %s, ret=%d", n.c_str(), ret); srs_error("unsupported directive %s, ret=%d", n.c_str(), ret);
return ret; return ret;
@ -3638,7 +3638,7 @@ int SrsConfig::check_config()
} }
} }
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// check listen for rtmp. // check listen for rtmp.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -3688,18 +3688,18 @@ int SrsConfig::check_config()
int max_open_files = (int)sysconf(_SC_OPEN_MAX); int max_open_files = (int)sysconf(_SC_OPEN_MAX);
int nb_canbe = max_open_files - nb_consumed_fds - 1; int nb_canbe = max_open_files - nb_consumed_fds - 1;
// for each play connections, we open a pipe(2fds) to convert SrsConsumver to io, // for each play connections, we open a pipe(2fds) to convert SrsConsumver to io,
// refine performance, @see: https://github.com/ossrs/srs/issues/194 // refine performance, @see: https://github.com/ossrs/srs/issues/194
if (nb_total >= max_open_files) { if (nb_total >= max_open_files) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("invalid max_connections=%d, required=%d, system limit to %d, " srs_error("invalid max_connections=%d, required=%d, system limit to %d, "
"total=%d(max_connections=%d, nb_consumed_fds=%d), ret=%d. " "total=%d(max_connections=%d, nb_consumed_fds=%d), ret=%d. "
"you can change max_connections from %d to %d, or " "you can change max_connections from %d to %d, or "
"you can login as root and set the limit: ulimit -HSn %d", "you can login as root and set the limit: ulimit -HSn %d",
nb_connections, nb_total + 100, max_open_files, nb_connections, nb_total + 100, max_open_files,
nb_total, nb_connections, nb_consumed_fds, nb_total, nb_connections, nb_consumed_fds,
ret, nb_connections, nb_canbe, nb_total + 100); ret, nb_connections, nb_canbe, nb_total + 100);
return ret; return ret;
} }
} }
@ -3709,18 +3709,18 @@ int SrsConfig::check_config()
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
if (get_heartbeat_interval() <= 0) { if (get_heartbeat_interval() <= 0) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("directive heartbeat interval invalid, interval=%"PRId64", ret=%d", srs_error("directive heartbeat interval invalid, interval=%"PRId64", ret=%d",
get_heartbeat_interval(), ret); get_heartbeat_interval(), ret);
return ret; return ret;
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// check stats // check stats
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
if (get_stats_network() < 0) { if (get_stats_network() < 0) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("directive stats network invalid, network=%d, ret=%d", srs_error("directive stats network invalid, network=%d, ret=%d",
get_stats_network(), ret); get_stats_network(), ret);
return ret; return ret;
} }
if (true) { if (true) {
@ -3729,7 +3729,7 @@ int SrsConfig::check_config()
if (index >= (int)ips.size()) { if (index >= (int)ips.size()) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("stats network invalid, total local ip count=%d, index=%d, ret=%d", 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; return ret;
} }
srs_warn("stats network use index=%d, ip=%s", index, ips.at(index).c_str()); 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()) { if (get_http_api_listen().empty()) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("directive http_api listen invalid, listen=%s, ret=%d", 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; return ret;
} }
@ -3764,10 +3764,10 @@ int SrsConfig::check_config()
if (get_http_stream_listen().empty()) { if (get_http_stream_listen().empty()) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("directive http_stream listen invalid, listen=%s, ret=%d", 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; return ret;
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// check log name and level // check log name and level
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -3805,7 +3805,7 @@ int SrsConfig::check_config()
} }
} }
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// check vhosts. // check vhosts.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -3823,7 +3823,7 @@ int SrsConfig::check_config()
&& n != "security" && n != "http_remux" && n != "dash" && n != "security" && n != "http_remux" && n != "dash"
&& n != "http_static" && n != "hds" && n != "exec" && n != "http_static" && n != "hds" && n != "exec"
&& n != "in_ack_size" && n != "out_ack_size" && n != "in_ack_size" && n != "out_ack_size"
) { ) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("unsupported vhost directive %s, ret=%d", n.c_str(), ret); srs_error("unsupported vhost directive %s, ret=%d", n.c_str(), ret);
return ret; return ret;
@ -3834,7 +3834,7 @@ int SrsConfig::check_config()
string m = conf->at(j)->name; string m = conf->at(j)->name;
if (m != "enabled" && m != "dvr_apply" && m != "dvr_path" && m != "dvr_plan" if (m != "enabled" && m != "dvr_apply" && m != "dvr_path" && m != "dvr_plan"
&& m != "dvr_duration" && m != "dvr_wait_keyframe" && m != "time_jitter" && m != "dvr_duration" && m != "dvr_wait_keyframe" && m != "time_jitter"
) { ) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("unsupported vhost dvr directive %s, ret=%d", m.c_str(), ret); srs_error("unsupported vhost dvr directive %s, ret=%d", m.c_str(), ret);
return ret; return ret;
@ -3863,7 +3863,7 @@ int SrsConfig::check_config()
string m = conf->at(j)->name; string m = conf->at(j)->name;
if (m != "time_jitter" && m != "mix_correct" && m != "atc" && m != "atc_auto" && m != "mw_latency" 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" && m != "gop_cache" && m != "queue_length" && m != "send_min_interval" && m != "reduce_sequence_header"
) { ) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("unsupported vhost play directive %s, ret=%d", m.c_str(), ret); srs_error("unsupported vhost play directive %s, ret=%d", m.c_str(), ret);
return ret; return ret;
@ -4015,13 +4015,13 @@ int SrsConfig::check_config()
for (int i = 0; i < (int)vhosts.size(); i++) { for (int i = 0; i < (int)vhosts.size(); i++) {
SrsConfDirective* vhost = vhosts[i]; SrsConfDirective* vhost = vhosts[i];
std::vector<std::string> ids; std::vector<std::string> ids;
for (int j = 0; j < (int)vhost->directives.size(); j++) { for (int j = 0; j < (int)vhost->directives.size(); j++) {
SrsConfDirective* conf = vhost->at(j); SrsConfDirective* conf = vhost->at(j);
if (conf->name != "ingest") { if (conf->name != "ingest") {
continue; continue;
} }
std::string id = conf->arg0(); std::string id = conf->arg0();
for (int k = 0; k < (int)ids.size(); k++) { for (int k = 0; k < (int)ids.size(); k++) {
if (id == ids.at(k)) { if (id == ids.at(k)) {
@ -4038,24 +4038,24 @@ int SrsConfig::check_config()
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// check chunk size // 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 || get_global_chunk_size() > SRS_CONSTS_RTMP_MAX_CHUNK_SIZE
) { ) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("directive chunk_size invalid, chunk_size=%d, must in [%d, %d], ret=%d", 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, get_global_chunk_size(), SRS_CONSTS_RTMP_MIN_CHUNK_SIZE,
SRS_CONSTS_RTMP_MAX_CHUNK_SIZE, ret); SRS_CONSTS_RTMP_MAX_CHUNK_SIZE, ret);
return ret; return ret;
} }
for (int i = 0; i < (int)vhosts.size(); i++) { for (int i = 0; i < (int)vhosts.size(); i++) {
SrsConfDirective* vhost = vhosts[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 || get_chunk_size(vhost->arg0()) > SRS_CONSTS_RTMP_MAX_CHUNK_SIZE
) { ) {
ret = ERROR_SYSTEM_CONFIG_INVALID; ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("directive vhost %s chunk_size invalid, chunk_size=%d, must in [%d, %d], ret=%d", 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, vhost->arg0().c_str(), get_chunk_size(vhost->arg0()), SRS_CONSTS_RTMP_MIN_CHUNK_SIZE,
SRS_CONSTS_RTMP_MAX_CHUNK_SIZE, ret); SRS_CONSTS_RTMP_MAX_CHUNK_SIZE, ret);
return ret; return ret;
} }
} }
@ -4078,9 +4078,9 @@ int SrsConfig::check_config()
for (int j = 0; j < (int)ingesters.size(); j++) { for (int j = 0; j < (int)ingesters.size(); j++) {
SrsConfDirective* ingest = ingesters[j]; SrsConfDirective* ingest = ingesters[j];
if (get_ingest_enabled(ingest)) { if (get_ingest_enabled(ingest)) {
srs_warn("ingest %s of vhost %s is disabled by configure", srs_warn("ingest %s of vhost %s is disabled by configure",
ingest->arg0().c_str(), vhost->arg0().c_str() ingest->arg0().c_str(), vhost->arg0().c_str()
); );
} }
} }
#endif #endif
@ -4121,7 +4121,7 @@ int SrsConfig::parse_buffer(SrsConfigBuffer* buffer)
set_config_directive(root, "daemon", "off"); set_config_directive(root, "daemon", "off");
set_config_directive(root, "srs_log_tank", "console"); set_config_directive(root, "srs_log_tank", "console");
} }
return ret; return ret;
} }
@ -4222,7 +4222,7 @@ string SrsConfig::get_work_dir() {
if( !conf || conf->arg0().empty()) { if( !conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
} }
return conf->arg0(); return conf->arg0();
return conf->arg0(); return conf->arg0();
@ -4282,12 +4282,12 @@ string SrsConfig::get_stream_caster_engine(SrsConfDirective* conf)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
conf = conf->get("caster"); conf = conf->get("caster");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
} }
return conf->arg0(); return conf->arg0();
} }
@ -4314,12 +4314,12 @@ int SrsConfig::get_stream_caster_listen(SrsConfDirective* conf)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
conf = conf->get("listen"); conf = conf->get("listen");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
} }
return ::atoi(conf->arg0().c_str()); 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<SrsConfDirective*>& vhosts) void SrsConfig::get_vhosts(vector<SrsConfDirective*>& vhosts)
{ {
srs_assert(root); srs_assert(root);
for (int i = 0; i < (int)root->directives.size(); i++) { for (int i = 0; i < (int)root->directives.size(); i++) {
SrsConfDirective* conf = root->at(i); SrsConfDirective* conf = root->at(i);
if (!conf->is_vhost()) { if (!conf->is_vhost()) {
continue; continue;
} }
vhosts.push_back(conf); vhosts.push_back(conf);
} }
} }
@ -4738,14 +4738,14 @@ int SrsConfig::get_chunk_size(string vhost)
// use the global instead. // use the global instead.
return get_global_chunk_size(); return get_global_chunk_size();
} }
conf = conf->get("chunk_size"); conf = conf->get("chunk_size");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
// vhost does not specify the chunk size, // vhost does not specify the chunk size,
// use the global instead. // use the global instead.
return get_global_chunk_size(); return get_global_chunk_size();
} }
return ::atoi(conf->arg0().c_str()); return ::atoi(conf->arg0().c_str());
} }
@ -4778,12 +4778,12 @@ bool SrsConfig::get_mr_enabled(string vhost)
if (!conf) { if (!conf) {
return SRS_PERF_MR_ENABLED; return SRS_PERF_MR_ENABLED;
} }
conf = conf->get("publish"); conf = conf->get("publish");
if (!conf) { if (!conf) {
return SRS_PERF_MR_ENABLED; return SRS_PERF_MR_ENABLED;
} }
conf = conf->get("mr"); conf = conf->get("mr");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return SRS_PERF_MR_ENABLED; return SRS_PERF_MR_ENABLED;
@ -4798,17 +4798,17 @@ int SrsConfig::get_mr_sleep_ms(string vhost)
if (!conf) { if (!conf) {
return SRS_PERF_MR_SLEEP; return SRS_PERF_MR_SLEEP;
} }
conf = conf->get("publish"); conf = conf->get("publish");
if (!conf) { if (!conf) {
return SRS_PERF_MR_SLEEP; return SRS_PERF_MR_SLEEP;
} }
conf = conf->get("mr_latency"); conf = conf->get("mr_latency");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return SRS_PERF_MR_SLEEP; return SRS_PERF_MR_SLEEP;
} }
return ::atoi(conf->arg0().c_str()); return ::atoi(conf->arg0().c_str());
} }
@ -4823,12 +4823,12 @@ int SrsConfig::get_mw_sleep_ms(string vhost)
if (!conf) { if (!conf) {
return SRS_PERF_MW_SLEEP; return SRS_PERF_MW_SLEEP;
} }
conf = conf->get("mw_latency"); conf = conf->get("mw_latency");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return SRS_PERF_MW_SLEEP; return SRS_PERF_MW_SLEEP;
} }
return ::atoi(conf->arg0().c_str()); return ::atoi(conf->arg0().c_str());
} }
@ -4838,12 +4838,12 @@ bool SrsConfig::get_realtime_enabled(string vhost)
if (!conf) { if (!conf) {
return SRS_PERF_MIN_LATENCY_ENABLED; return SRS_PERF_MIN_LATENCY_ENABLED;
} }
conf = conf->get("min_latency"); conf = conf->get("min_latency");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return SRS_PERF_MIN_LATENCY_ENABLED; return SRS_PERF_MIN_LATENCY_ENABLED;
} }
return SRS_CONF_PERFER_FALSE(conf->arg0()); 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* SrsConfig::get_vhost_http_hooks(string vhost)
{ {
SrsConfDirective* conf = get_vhost(vhost); SrsConfDirective* conf = get_vhost(vhost);
if (!conf) { if (!conf) {
return NULL; return NULL;
} }
@ -5016,9 +5016,9 @@ SrsConfDirective* SrsConfig::get_vhost_http_hooks(string vhost)
bool SrsConfig::get_vhost_http_hooks_enabled(string vhost) bool SrsConfig::get_vhost_http_hooks_enabled(string vhost)
{ {
static bool DEFAULT = false; static bool DEFAULT = false;
SrsConfDirective* conf = get_vhost_http_hooks(vhost); SrsConfDirective* conf = get_vhost_http_hooks(vhost);
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
@ -5033,7 +5033,7 @@ bool SrsConfig::get_vhost_http_hooks_enabled(string vhost)
SrsConfDirective* SrsConfig::get_vhost_on_connect(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_connect(string vhost)
{ {
SrsConfDirective* conf = get_vhost_http_hooks(vhost); SrsConfDirective* conf = get_vhost_http_hooks(vhost);
if (!conf) { if (!conf) {
return NULL; return NULL;
} }
@ -5043,7 +5043,7 @@ SrsConfDirective* SrsConfig::get_vhost_on_connect(string vhost)
SrsConfDirective* SrsConfig::get_vhost_on_close(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_close(string vhost)
{ {
SrsConfDirective* conf = get_vhost_http_hooks(vhost); SrsConfDirective* conf = get_vhost_http_hooks(vhost);
if (!conf) { if (!conf) {
return NULL; return NULL;
} }
@ -5053,7 +5053,7 @@ SrsConfDirective* SrsConfig::get_vhost_on_close(string vhost)
SrsConfDirective* SrsConfig::get_vhost_on_publish(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_publish(string vhost)
{ {
SrsConfDirective* conf = get_vhost_http_hooks(vhost); SrsConfDirective* conf = get_vhost_http_hooks(vhost);
if (!conf) { if (!conf) {
return NULL; return NULL;
} }
@ -5063,7 +5063,7 @@ SrsConfDirective* SrsConfig::get_vhost_on_publish(string vhost)
SrsConfDirective* SrsConfig::get_vhost_on_unpublish(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_unpublish(string vhost)
{ {
SrsConfDirective* conf = get_vhost_http_hooks(vhost); SrsConfDirective* conf = get_vhost_http_hooks(vhost);
if (!conf) { if (!conf) {
return NULL; return NULL;
} }
@ -5073,7 +5073,7 @@ SrsConfDirective* SrsConfig::get_vhost_on_unpublish(string vhost)
SrsConfDirective* SrsConfig::get_vhost_on_play(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_play(string vhost)
{ {
SrsConfDirective* conf = get_vhost_http_hooks(vhost); SrsConfDirective* conf = get_vhost_http_hooks(vhost);
if (!conf) { if (!conf) {
return NULL; return NULL;
} }
@ -5083,7 +5083,7 @@ SrsConfDirective* SrsConfig::get_vhost_on_play(string vhost)
SrsConfDirective* SrsConfig::get_vhost_on_stop(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_stop(string vhost)
{ {
SrsConfDirective* conf = get_vhost_http_hooks(vhost); SrsConfDirective* conf = get_vhost_http_hooks(vhost);
if (!conf) { if (!conf) {
return NULL; return NULL;
} }
@ -5128,12 +5128,12 @@ bool SrsConfig::get_bw_check_enabled(string vhost)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
conf = conf->get("bandcheck"); conf = conf->get("bandcheck");
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
conf = conf->get("enabled"); conf = conf->get("enabled");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
@ -5150,7 +5150,7 @@ string SrsConfig::get_bw_check_key(string vhost)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
conf = conf->get("bandcheck"); conf = conf->get("bandcheck");
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
@ -5160,7 +5160,7 @@ string SrsConfig::get_bw_check_key(string vhost)
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
} }
return conf->arg0(); return conf->arg0();
} }
@ -5172,7 +5172,7 @@ int SrsConfig::get_bw_check_interval_ms(string vhost)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
conf = conf->get("bandcheck"); conf = conf->get("bandcheck");
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
@ -5182,7 +5182,7 @@ int SrsConfig::get_bw_check_interval_ms(string vhost)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
return (int)(::atof(conf->arg0().c_str()) * 1000); return (int)(::atof(conf->arg0().c_str()) * 1000);
} }
@ -5194,7 +5194,7 @@ int SrsConfig::get_bw_check_limit_kbps(string vhost)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
conf = conf->get("bandcheck"); conf = conf->get("bandcheck");
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
@ -5204,7 +5204,7 @@ int SrsConfig::get_bw_check_limit_kbps(string vhost)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
return ::atoi(conf->arg0().c_str()); return ::atoi(conf->arg0().c_str());
} }
@ -5227,12 +5227,12 @@ bool SrsConfig::get_vhost_is_edge(SrsConfDirective* vhost)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
conf = conf->get("mode"); conf = conf->get("mode");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
} }
return "remote" == conf->arg0(); return "remote" == conf->arg0();
} }
@ -5617,7 +5617,7 @@ string SrsConfig::get_engine_vpreset(SrsConfDirective* conf)
vector<string> SrsConfig::get_engine_vparams(SrsConfDirective* conf) vector<string> SrsConfig::get_engine_vparams(SrsConfDirective* conf)
{ {
vector<string> vparams; vector<string> vparams;
if (!conf) { if (!conf) {
return vparams; return vparams;
} }
@ -5882,7 +5882,7 @@ string SrsConfig::get_ingest_input_type(SrsConfDirective* conf)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
conf = conf->get("type"); conf = conf->get("type");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
@ -5903,7 +5903,7 @@ string SrsConfig::get_ingest_input_url(SrsConfDirective* conf)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
conf = conf->get("url"); conf = conf->get("url");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
@ -6111,7 +6111,7 @@ string SrsConfig::get_hls_entry_prefix(string vhost)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
return conf->arg0(); return conf->arg0();
} }
@ -6196,7 +6196,7 @@ double SrsConfig::get_hls_fragment(string vhost)
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
} }
return ::atof(conf->arg0().c_str()); return ::atof(conf->arg0().c_str());
} }
@ -6265,7 +6265,7 @@ string SrsConfig::get_hls_on_error(string vhost)
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
} }
return conf->arg0(); return conf->arg0();
} }
@ -6374,11 +6374,11 @@ bool SrsConfig::get_hls_wait_keyframe(string vhost)
SrsConfDirective *SrsConfig::get_hds(const string &vhost) SrsConfDirective *SrsConfig::get_hds(const string &vhost)
{ {
SrsConfDirective* conf = get_vhost(vhost); SrsConfDirective* conf = get_vhost(vhost);
if (!conf) { if (!conf) {
return NULL; return NULL;
} }
return conf->get("hds"); return conf->get("hds");
} }
@ -6390,7 +6390,7 @@ bool SrsConfig::get_hds_enabled(const string &vhost)
if (!conf) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
conf = conf->get("enabled"); conf = conf->get("enabled");
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
@ -6615,7 +6615,7 @@ string SrsConfig::get_http_api_listen()
if (!conf || conf->arg0().empty()) { if (!conf || conf->arg0().empty()) {
return DEFAULT; return DEFAULT;
} }
return conf->arg0(); return conf->arg0();
} }

File diff suppressed because it is too large Load diff

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_conn.hpp> #include <srs_app_conn.hpp>
@ -47,12 +47,12 @@ SrsConnection::SrsConnection(IConnectionManager* cm, st_netfd_t c, string cip)
disposed = false; disposed = false;
expired = false; expired = false;
create_time = srs_get_system_time_ms(); create_time = srs_get_system_time_ms();
skt = new SrsStSocket(); skt = new SrsStSocket();
kbps = new SrsKbps(); kbps = new SrsKbps();
kbps->set_io(skt, skt); kbps->set_io(skt, skt);
// the client thread should reap itself, // the client thread should reap itself,
// so we never use joinable. // so we never use joinable.
// TODO: FIXME: maybe other thread need to stop it. // TODO: FIXME: maybe other thread need to stop it.
// @see: https://github.com/ossrs/srs/issues/78 // @see: https://github.com/ossrs/srs/issues/78
@ -62,7 +62,7 @@ SrsConnection::SrsConnection(IConnectionManager* cm, st_netfd_t c, string cip)
SrsConnection::~SrsConnection() SrsConnection::~SrsConnection()
{ {
dispose(); dispose();
srs_freep(kbps); srs_freep(kbps);
srs_freep(skt); srs_freep(skt);
srs_freep(pthread); srs_freep(pthread);
@ -137,7 +137,7 @@ int SrsConnection::cycle()
if (ret == ERROR_SOCKET_CLOSED) { if (ret == ERROR_SOCKET_CLOSED) {
srs_warn("client disconnect peer. oret=%d, ret=%d", oret, ret); srs_warn("client disconnect peer. oret=%d, ret=%d", oret, ret);
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_CONN_HPP #ifndef SRS_APP_CONN_HPP
#define SRS_APP_CONN_HPP #define SRS_APP_CONN_HPP
/*
#include <srs_app_conn.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
@ -55,34 +51,34 @@ public:
}; };
/** /**
* the basic connection of SRS, * the basic connection of SRS,
* all connections accept from listener must extends from this base class, * all connections accept from listener must extends from this base class,
* server will add the connection to manager, and delete it when remove. * server will add the connection to manager, and delete it when remove.
*/ */
class SrsConnection : virtual public ISrsOneCycleThreadHandler, virtual public IKbpsDelta, virtual public ISrsReloadHandler class SrsConnection : virtual public ISrsOneCycleThreadHandler, virtual public IKbpsDelta, virtual public ISrsReloadHandler
{ {
private: private:
/** /**
* each connection start a green thread, * each connection start a green thread,
* when thread stop, the connection will be delete by server. * when thread stop, the connection will be delete by server.
*/ */
SrsOneCycleThread* pthread; SrsOneCycleThread* pthread;
/** /**
* the id of connection. * the id of connection.
*/ */
int id; int id;
protected: protected:
/** /**
* the manager object to manage the connection. * the manager object to manage the connection.
*/ */
IConnectionManager* manager; IConnectionManager* manager;
/** /**
* the underlayer st fd handler. * the underlayer st fd handler.
*/ */
st_netfd_t stfd; st_netfd_t stfd;
/** /**
* the ip of client. * the ip of client.
*/ */
std::string ip; std::string ip;
/** /**
* whether the connection is disposed, * whether the connection is disposed,
@ -95,8 +91,8 @@ protected:
*/ */
bool expired; bool expired;
/** /**
* the underlayer socket. * the underlayer socket.
*/ */
SrsStSocket* skt; SrsStSocket* skt;
/** /**
* connection total kbps. * connection total kbps.
@ -125,33 +121,33 @@ public:
*/ */
virtual void dispose(); virtual void dispose();
/** /**
* start the client green thread. * start the client green thread.
* when server get a client from listener, * when server get a client from listener,
* 1. server will create an concrete connection(for instance, RTMP connection), * 1. server will create an concrete connection(for instance, RTMP connection),
* 2. then add connection to its connection manager, * 2. then add connection to its connection manager,
* 3. start the client thread by invoke this start() * 3. start the client thread by invoke this start()
* when client cycle thread stop, invoke the on_thread_stop(), which will use server * when client cycle thread stop, invoke the on_thread_stop(), which will use server
* to remove the client by server->remove(this). * to remove the client by server->remove(this).
*/ */
virtual int start(); virtual int start();
// interface ISrsOneCycleThreadHandler // interface ISrsOneCycleThreadHandler
public: public:
/** /**
* the thread cycle function, * the thread cycle function,
* when serve connection completed, terminate the loop which will terminate the thread, * when serve connection completed, terminate the loop which will terminate the thread,
* thread will invoke the on_thread_stop() when it terminated. * thread will invoke the on_thread_stop() when it terminated.
*/ */
virtual int cycle(); virtual int cycle();
/** /**
* when the thread cycle finished, thread will invoke the on_thread_stop(), * 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 * which will remove self from server, server will remove the connection from manager
* then delete the connection. * then delete the connection.
*/ */
virtual void on_thread_stop(); virtual void on_thread_stop();
public: public:
/** /**
* get the srs id which identify the client. * get the srs id which identify the client.
*/ */
virtual int srs_id(); virtual int srs_id();
/** /**
* set connection to expired. * set connection to expired.
@ -159,8 +155,8 @@ public:
virtual void expire(); virtual void expire();
protected: protected:
/** /**
* for concrete connection to do the cycle. * for concrete connection to do the cycle.
*/ */
virtual int do_cycle() = 0; virtual int do_cycle() = 0;
}; };

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_dash.hpp> #include <srs_app_dash.hpp>
@ -399,19 +399,19 @@ int SrsMpdWriter::write(SrsFormat* format)
stringstream ss; stringstream ss;
ss << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << endl ss << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << endl
<< "<MPD profiles=\"urn:mpeg:dash:profile:isoff-live:2011,http://dashif.org/guidelines/dash-if-simple\" " << endl << "<MPD profiles=\"urn:mpeg:dash:profile:isoff-live:2011,http://dashif.org/guidelines/dash-if-simple\" " << endl
<< " ns1:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" " << endl << " ns1:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" " << endl
<< " xmlns=\"urn:mpeg:dash:schema:mpd:2011\" xmlns:ns1=\"http://www.w3.org/2001/XMLSchema-instance\" " << endl << " xmlns=\"urn:mpeg:dash:schema:mpd:2011\" xmlns:ns1=\"http://www.w3.org/2001/XMLSchema-instance\" " << endl
<< " type=\"dynamic\" minimumUpdatePeriod=\"PT" << update_period / 1000 << "S\" " << endl << " type=\"dynamic\" minimumUpdatePeriod=\"PT" << update_period / 1000 << "S\" " << endl
<< " timeShiftBufferDepth=\"PT" << timeshit / 1000 << "S\" availabilityStartTime=\"1970-01-01T00:00:00Z\" " << endl << " timeShiftBufferDepth=\"PT" << timeshit / 1000 << "S\" availabilityStartTime=\"1970-01-01T00:00:00Z\" " << endl
<< " maxSegmentDuration=\"PT" << fragment / 1000 << "S\" minBufferTime=\"PT" << fragment / 1000 << "S\" >" << endl << " maxSegmentDuration=\"PT" << fragment / 1000 << "S\" minBufferTime=\"PT" << fragment / 1000 << "S\" >" << endl
<< " <BaseURL>" << req->stream << "/" << "</BaseURL>" << endl << " <BaseURL>" << req->stream << "/" << "</BaseURL>" << endl
<< " <Period start=\"PT0S\">" << endl; << " <Period start=\"PT0S\">" << endl;
if (format->acodec) { if (format->acodec) {
ss << " <AdaptationSet mimeType=\"audio/mp4\" segmentAlignment=\"true\" startWithSAP=\"1\">" << endl; ss << " <AdaptationSet mimeType=\"audio/mp4\" segmentAlignment=\"true\" startWithSAP=\"1\">" << endl;
ss << " <SegmentTemplate duration=\"" << fragment / 1000 << "\" " ss << " <SegmentTemplate duration=\"" << fragment / 1000 << "\" "
<< "initialization=\"$RepresentationID$-init.mp4\" " << "initialization=\"$RepresentationID$-init.mp4\" "
<< "media=\"$RepresentationID$-$Number$.m4s\" />" << endl; << "media=\"$RepresentationID$-$Number$.m4s\" />" << endl;
ss << " <Representation id=\"audio\" bandwidth=\"48000\" codecs=\"mp4a.40.2\" />" << endl; ss << " <Representation id=\"audio\" bandwidth=\"48000\" codecs=\"mp4a.40.2\" />" << endl;
ss << " </AdaptationSet>" << endl; ss << " </AdaptationSet>" << endl;
} }
@ -420,14 +420,14 @@ int SrsMpdWriter::write(SrsFormat* format)
int h = format->vcodec->height; int h = format->vcodec->height;
ss << " <AdaptationSet mimeType=\"video/mp4\" segmentAlignment=\"true\" startWithSAP=\"1\">" << endl; ss << " <AdaptationSet mimeType=\"video/mp4\" segmentAlignment=\"true\" startWithSAP=\"1\">" << endl;
ss << " <SegmentTemplate duration=\"" << fragment / 1000 << "\" " ss << " <SegmentTemplate duration=\"" << fragment / 1000 << "\" "
<< "initialization=\"$RepresentationID$-init.mp4\" " << "initialization=\"$RepresentationID$-init.mp4\" "
<< "media=\"$RepresentationID$-$Number$.m4s\" />" << endl; << "media=\"$RepresentationID$-$Number$.m4s\" />" << endl;
ss << " <Representation id=\"video\" bandwidth=\"800000\" codecs=\"avc1.64001e\" " ss << " <Representation id=\"video\" bandwidth=\"800000\" codecs=\"avc1.64001e\" "
<< "width=\"" << w << "\" height=\"" << h << "\"/>" << endl; << "width=\"" << w << "\" height=\"" << h << "\"/>" << endl;
ss << " </AdaptationSet>" << endl; ss << " </AdaptationSet>" << endl;
} }
ss << " </Period>" << endl ss << " </Period>" << endl
<< "</MPD>" << endl; << "</MPD>" << endl;
SrsFileWriter* fw = new SrsFileWriter(); SrsFileWriter* fw = new SrsFileWriter();
SrsAutoFree(SrsFileWriter, fw); SrsAutoFree(SrsFileWriter, fw);
@ -566,7 +566,7 @@ int SrsDashController::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* fo
} }
bool reopen = format->video->frame_type == SrsVideoAvcFrameTypeKeyFrame bool reopen = format->video->frame_type == SrsVideoAvcFrameTypeKeyFrame
&& vcurrent->duration() >= fragment; && vcurrent->duration() >= fragment;
if (reopen) { if (reopen) {
if ((ret = vcurrent->reap()) != ERROR_SUCCESS) { if ((ret = vcurrent->reap()) != ERROR_SUCCESS) {
return ret; return ret;

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_DASH_HPP #ifndef SRS_APP_DASH_HPP
#define SRS_APP_DASH_HPP #define SRS_APP_DASH_HPP
/*
#include <srs_app_dash.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_dvr.hpp> #include <srs_app_dvr.hpp>
@ -52,14 +52,14 @@ SrsDvrSegmenter::SrsDvrSegmenter()
fragment = new SrsFragment(); fragment = new SrsFragment();
fs = new SrsFileWriter(); fs = new SrsFileWriter();
jitter_algorithm = SrsRtmpJitterAlgorithmOFF; jitter_algorithm = SrsRtmpJitterAlgorithmOFF;
_srs_config->subscribe(this); _srs_config->subscribe(this);
} }
SrsDvrSegmenter::~SrsDvrSegmenter() SrsDvrSegmenter::~SrsDvrSegmenter()
{ {
_srs_config->unsubscribe(this); _srs_config->unsubscribe(this);
srs_freep(fragment); srs_freep(fragment);
srs_freep(jitter); srs_freep(jitter);
srs_freep(fs); 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); jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_dvr_time_jitter(req->vhost);
wait_keyframe = _srs_config->get_dvr_wait_keyframe(req->vhost); wait_keyframe = _srs_config->get_dvr_wait_keyframe(req->vhost);
return ret; return ret;
} }
@ -91,7 +91,7 @@ int SrsDvrSegmenter::open()
if (fs->is_open()) { if (fs->is_open()) {
return ret; return ret;
} }
string path = generate_path(); string path = generate_path();
if (srs_path_exists(path)) { if (srs_path_exists(path)) {
ret = ERROR_DVR_CANNOT_APPEND; ret = ERROR_DVR_CANNOT_APPEND;
@ -104,7 +104,7 @@ int SrsDvrSegmenter::open()
if ((ret = fragment->create_dir()) != ERROR_SUCCESS) { if ((ret = fragment->create_dir()) != ERROR_SUCCESS) {
return ret; return ret;
} }
// create jitter. // create jitter.
srs_freep(jitter); srs_freep(jitter);
jitter = new SrsRtmpJitter(); 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); srs_error("open file stream for file %s failed. ret=%d", path.c_str(), ret);
return ret; return ret;
} }
// initialize the encoder. // initialize the encoder.
if ((ret = open_encoder()) != ERROR_SUCCESS) { if ((ret = open_encoder()) != ERROR_SUCCESS) {
srs_error("initialize enc by fs for file %s failed. ret=%d", path.c_str(), ret); 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()); srs_trace("dvr stream %s to file %s", req->stream.c_str(), path.c_str());
return ret; return ret;
} }
@ -184,7 +184,7 @@ int SrsDvrSegmenter::close()
if (!fs->is_open()) { if (!fs->is_open()) {
return ret; return ret;
} }
// Close the encoder, then close the fs object. // Close the encoder, then close the fs object.
if ((ret = close_encoder()) != ERROR_SUCCESS) { if ((ret = close_encoder()) != ERROR_SUCCESS) {
return ret; return ret;
@ -196,14 +196,14 @@ int SrsDvrSegmenter::close()
if ((ret = fragment->rename()) != ERROR_SUCCESS) { if ((ret = fragment->rename()) != ERROR_SUCCESS) {
return ret; return ret;
} }
// TODO: FIXME: the http callback is async, which will trigger thread switch, // TODO: FIXME: the http callback is async, which will trigger thread switch,
// so the on_video maybe invoked during the http callback, and error. // so the on_video maybe invoked during the http callback, and error.
if ((ret = plan->on_reap_segment()) != ERROR_SUCCESS) { if ((ret = plan->on_reap_segment()) != ERROR_SUCCESS) {
srs_error("dvr: notify plan to reap segment failed. ret=%d", ret); srs_error("dvr: notify plan to reap segment failed. ret=%d", ret);
return ret; return ret;
} }
return ret; return ret;
} }
@ -218,7 +218,7 @@ int SrsDvrSegmenter::on_update_duration(SrsSharedPtrMessage* msg)
string SrsDvrSegmenter::generate_path() 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 // /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv
std::string path_config = _srs_config->get_dvr_path(req->vhost); 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; 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_stream(flv_path, req->vhost, req->app, req->stream);
flv_path = srs_path_build_timestamp(flv_path); flv_path = srs_path_build_timestamp(flv_path);
return flv_path; return flv_path;
} }
@ -336,7 +336,7 @@ int SrsDvrFlvSegmenter::open_encoder()
if ((ret = enc->initialize(fs)) != ERROR_SUCCESS) { if ((ret = enc->initialize(fs)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// write the flv header to writer. // write the flv header to writer.
if ((ret = enc->write_header()) != ERROR_SUCCESS) { if ((ret = enc->write_header()) != ERROR_SUCCESS) {
srs_error("write flv header failed. ret=%d", ret); srs_error("write flv header failed. ret=%d", ret);
@ -430,7 +430,7 @@ int SrsDvrFlvSegmenter::encode_video(SrsSharedPtrMessage* video)
int size = video->size; int size = video->size;
bool sh = SrsFlvVideo::sh(payload, size); bool sh = SrsFlvVideo::sh(payload, size);
bool keyframe = SrsFlvVideo::h264(payload, size) bool keyframe = SrsFlvVideo::h264(payload, size)
&& SrsFlvVideo::keyframe(payload, size) && !sh; && SrsFlvVideo::keyframe(payload, size) && !sh;
if (keyframe) { if (keyframe) {
has_keyframe = true; has_keyframe = true;
@ -630,7 +630,7 @@ int SrsDvrAsyncCallOnDvr::call()
return ret; return ret;
} }
} }
return ret; return ret;
} }
@ -644,7 +644,7 @@ string SrsDvrAsyncCallOnDvr::to_string()
SrsDvrPlan::SrsDvrPlan() SrsDvrPlan::SrsDvrPlan()
{ {
req = NULL; req = NULL;
dvr_enabled = false; dvr_enabled = false;
segment = NULL; segment = NULL;
async = new SrsAsyncCallWorker(); async = new SrsAsyncCallWorker();
@ -663,15 +663,15 @@ int SrsDvrPlan::initialize(SrsOriginHub* h, SrsDvrSegmenter* s, SrsRequest* r)
hub = h; hub = h;
req = r; req = r;
segment = s; segment = s;
if ((ret = segment->initialize(this, r)) != ERROR_SUCCESS) { if ((ret = segment->initialize(this, r)) != ERROR_SUCCESS) {
return ret; return ret;
} }
if ((ret = async->start()) != ERROR_SUCCESS) { if ((ret = async->start()) != ERROR_SUCCESS) {
return ret; return ret;
} }
return ret; return ret;
} }
@ -693,7 +693,7 @@ int SrsDvrPlan::on_audio(SrsSharedPtrMessage* shared_audio)
if (!dvr_enabled) { if (!dvr_enabled) {
return ret; return ret;
} }
if ((ret = segment->write_audio(shared_audio)) != ERROR_SUCCESS) { if ((ret = segment->write_audio(shared_audio)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -708,7 +708,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* shared_video)
if (!dvr_enabled) { if (!dvr_enabled) {
return ret; return ret;
} }
if ((ret = segment->write_video(shared_video)) != ERROR_SUCCESS) { if ((ret = segment->write_video(shared_video)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -719,7 +719,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* shared_video)
int SrsDvrPlan::on_reap_segment() int SrsDvrPlan::on_reap_segment()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
int cid = _srs_context->get_id(); int cid = _srs_context->get_id();
SrsFragment* fragment = segment->current(); SrsFragment* fragment = segment->current();
@ -728,7 +728,7 @@ int SrsDvrPlan::on_reap_segment()
if ((ret = async->execute(new SrsDvrAsyncCallOnDvr(cid, req, fullpath))) != ERROR_SUCCESS) { if ((ret = async->execute(new SrsDvrAsyncCallOnDvr(cid, req, fullpath))) != ERROR_SUCCESS) {
return ret; return ret;
} }
return ret; return ret;
} }
@ -766,21 +766,21 @@ int SrsDvrSessionPlan::on_publish()
if (dvr_enabled) { if (dvr_enabled) {
return ret; return ret;
} }
if (!_srs_config->get_dvr_enabled(req->vhost)) { if (!_srs_config->get_dvr_enabled(req->vhost)) {
return ret; return ret;
} }
if ((ret = segment->close()) != ERROR_SUCCESS) { if ((ret = segment->close()) != ERROR_SUCCESS) {
return ret; return ret;
} }
if ((ret = segment->open()) != ERROR_SUCCESS) { if ((ret = segment->open()) != ERROR_SUCCESS) {
return ret; return ret;
} }
dvr_enabled = true; dvr_enabled = true;
return ret; return ret;
} }
@ -835,21 +835,21 @@ int SrsDvrSegmentPlan::on_publish()
if (dvr_enabled) { if (dvr_enabled) {
return ret; return ret;
} }
if (!_srs_config->get_dvr_enabled(req->vhost)) { if (!_srs_config->get_dvr_enabled(req->vhost)) {
return ret; return ret;
} }
if ((ret = segment->close()) != ERROR_SUCCESS) { if ((ret = segment->close()) != ERROR_SUCCESS) {
return ret; return ret;
} }
if ((ret = segment->open()) != ERROR_SUCCESS) { if ((ret = segment->open()) != ERROR_SUCCESS) {
return ret; return ret;
} }
dvr_enabled = true; dvr_enabled = true;
return ret; return ret;
} }
@ -860,7 +860,7 @@ void SrsDvrSegmentPlan::on_unpublish()
int SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage* shared_audio) int SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage* shared_audio)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if ((ret = update_duration(shared_audio)) != ERROR_SUCCESS) { if ((ret = update_duration(shared_audio)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -868,14 +868,14 @@ int SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage* shared_audio)
if ((ret = SrsDvrPlan::on_audio(shared_audio)) != ERROR_SUCCESS) { if ((ret = SrsDvrPlan::on_audio(shared_audio)) != ERROR_SUCCESS) {
return ret; return ret;
} }
return ret; return ret;
} }
int SrsDvrSegmentPlan::on_video(SrsSharedPtrMessage* shared_video) int SrsDvrSegmentPlan::on_video(SrsSharedPtrMessage* shared_video)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if ((ret = update_duration(shared_video)) != ERROR_SUCCESS) { if ((ret = update_duration(shared_video)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -883,7 +883,7 @@ int SrsDvrSegmentPlan::on_video(SrsSharedPtrMessage* shared_video)
if ((ret = SrsDvrPlan::on_video(shared_video)) != ERROR_SUCCESS) { if ((ret = SrsDvrPlan::on_video(shared_video)) != ERROR_SUCCESS) {
return ret; return ret;
} }
return ret; return ret;
} }
@ -909,8 +909,8 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
char* payload = msg->payload; char* payload = msg->payload;
int size = msg->size; int size = msg->size;
bool is_key_frame = SrsFlvVideo::h264(payload, size) bool is_key_frame = SrsFlvVideo::h264(payload, size)
&& SrsFlvVideo::keyframe(payload, size) && SrsFlvVideo::keyframe(payload, size)
&& !SrsFlvVideo::sh(payload, size); && !SrsFlvVideo::sh(payload, size);
if (!is_key_frame) { if (!is_key_frame) {
return ret; return ret;
} }
@ -971,7 +971,7 @@ SrsDvr::~SrsDvr()
int SrsDvr::initialize(SrsOriginHub* h, SrsRequest* r) int SrsDvr::initialize(SrsOriginHub* h, SrsRequest* r)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
req = r; req = r;
hub = h; hub = h;
@ -1027,7 +1027,7 @@ int SrsDvr::on_meta_data(SrsSharedPtrMessage* metadata)
if (!actived) { if (!actived) {
return ret; return ret;
} }
if ((ret = plan->on_meta_data(metadata)) != ERROR_SUCCESS) { if ((ret = plan->on_meta_data(metadata)) != ERROR_SUCCESS) {
return ret; return ret;
} }

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_DVR_HPP #ifndef SRS_APP_DVR_HPP
#define SRS_APP_DVR_HPP #define SRS_APP_DVR_HPP
/*
#include <srs_app_dvr.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
@ -166,8 +163,8 @@ protected:
}; };
/** /**
* the dvr async call. * the dvr async call.
*/ */
class SrsDvrAsyncCallOnDvr : public ISrsAsyncCallTask class SrsDvrAsyncCallOnDvr : public ISrsAsyncCallTask
{ {
private: private:
@ -184,7 +181,7 @@ public:
/** /**
* The DVR plan, when and how to reap segment. * The DVR plan, when and how to reap segment.
*/ */
class SrsDvrPlan : public ISrsReloadHandler class SrsDvrPlan : public ISrsReloadHandler
{ {
public: public:
@ -204,7 +201,7 @@ public:
virtual int on_meta_data(SrsSharedPtrMessage* shared_metadata); virtual int on_meta_data(SrsSharedPtrMessage* shared_metadata);
virtual int on_audio(SrsSharedPtrMessage* shared_audio); virtual int on_audio(SrsSharedPtrMessage* shared_audio);
virtual int on_video(SrsSharedPtrMessage* shared_video); virtual int on_video(SrsSharedPtrMessage* shared_video);
// Internal interface for segmenter. // Internal interface for segmenter.
public: public:
// When segmenter close a segment. // When segmenter close a segment.
virtual int on_reap_segment(); virtual int on_reap_segment();
@ -281,23 +278,23 @@ public:
*/ */
virtual int on_publish(); virtual int on_publish();
/** /**
* the unpublish event., * the unpublish event.,
* when encoder stop(unpublish) to publish RTMP stream. * when encoder stop(unpublish) to publish RTMP stream.
*/ */
virtual void on_unpublish(); 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); virtual int on_meta_data(SrsSharedPtrMessage* metadata);
/** /**
* mux the audio packets to dvr. * mux the audio packets to dvr.
* @param shared_audio, directly ptr, copy it if need to save it. * @param shared_audio, directly ptr, copy it if need to save it.
*/ */
virtual int on_audio(SrsSharedPtrMessage* shared_audio); virtual int on_audio(SrsSharedPtrMessage* shared_audio);
/** /**
* mux the video packets to dvr. * mux the video packets to dvr.
* @param shared_video, directly ptr, copy it if need to save it. * @param shared_video, directly ptr, copy it if need to save it.
*/ */
virtual int on_video(SrsSharedPtrMessage* shared_video); virtual int on_video(SrsSharedPtrMessage* shared_video);
// interface ISrsReloadHandler // interface ISrsReloadHandler
public: public:

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_edge.hpp> #include <srs_app_edge.hpp>
@ -176,7 +176,7 @@ SrsEdgeIngester::SrsEdgeIngester()
} }
SrsEdgeIngester::~SrsEdgeIngester() SrsEdgeIngester::~SrsEdgeIngester()
{ {
stop(); stop();
srs_freep(upstream); srs_freep(upstream);
@ -198,12 +198,12 @@ int SrsEdgeIngester::initialize(SrsSource* s, SrsPlayEdge* e, SrsRequest* r)
int SrsEdgeIngester::start() int SrsEdgeIngester::start()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if ((ret = source->on_publish()) != ERROR_SUCCESS) { if ((ret = source->on_publish()) != ERROR_SUCCESS) {
srs_error("edge pull stream then publish to edge failed. ret=%d", ret); srs_error("edge pull stream then publish to edge failed. ret=%d", ret);
return ret; return ret;
} }
return pthread->start(); return pthread->start();
} }
@ -307,7 +307,7 @@ int SrsEdgeIngester::ingest()
int SrsEdgeIngester::process_publish_message(SrsCommonMessage* msg) int SrsEdgeIngester::process_publish_message(SrsCommonMessage* msg)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// process audio packet // process audio packet
if (msg->header.is_audio()) { if (msg->header.is_audio()) {
if ((ret = source->on_audio(msg)) != ERROR_SUCCESS) { if ((ret = source->on_audio(msg)) != ERROR_SUCCESS) {
@ -332,7 +332,7 @@ int SrsEdgeIngester::process_publish_message(SrsCommonMessage* msg)
} }
return ret; return ret;
} }
// process onMetaData // process onMetaData
if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) { if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) {
SrsPacket* pkt = NULL; SrsPacket* pkt = NULL;
@ -341,7 +341,7 @@ int SrsEdgeIngester::process_publish_message(SrsCommonMessage* msg)
return ret; return ret;
} }
SrsAutoFree(SrsPacket, pkt); SrsAutoFree(SrsPacket, pkt);
if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) { if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) {
SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt); SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt);
if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) { if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) {
@ -500,13 +500,13 @@ int SrsEdgeForwarder::cycle()
SrsAutoFree(SrsPithyPrint, pprint); SrsAutoFree(SrsPithyPrint, pprint);
SrsMessageArray msgs(SYS_MAX_EDGE_SEND_MSGS); SrsMessageArray msgs(SYS_MAX_EDGE_SEND_MSGS);
while (!pthread->interrupted()) { while (!pthread->interrupted()) {
if (send_error_code != ERROR_SUCCESS) { if (send_error_code != ERROR_SUCCESS) {
st_usleep(SRS_EDGE_FORWARDER_TMMS * 1000); st_usleep(SRS_EDGE_FORWARDER_TMMS * 1000);
continue; continue;
} }
// read from client. // read from client.
if (true) { if (true) {
SrsCommonMessage* msg = NULL; SrsCommonMessage* msg = NULL;
@ -542,7 +542,7 @@ int SrsEdgeForwarder::cycle()
srs_verbose("edge no packets to push."); srs_verbose("edge no packets to push.");
continue; continue;
} }
// sendout messages, all messages are freed by send_and_free_messages(). // sendout messages, all messages are freed by send_and_free_messages().
if ((ret = sdk->send_and_free_messages(msgs.msgs, count)) != ERROR_SUCCESS) { if ((ret = sdk->send_and_free_messages(msgs.msgs, count)) != ERROR_SUCCESS) {
srs_error("edge publish push message to server failed. ret=%d", ret); 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_set_chunk_size()
|| msg->header.is_window_ackledgement_size() || msg->header.is_window_ackledgement_size()
|| msg->header.is_ackledgement() || msg->header.is_ackledgement()
) { ) {
return ret; return ret;
} }
@ -618,7 +618,7 @@ int SrsPlayEdge::on_client_play()
state = SrsEdgeStatePlay; state = SrsEdgeStatePlay;
return ingester->start(); return ingester->start();
} }
return ret; return ret;
} }
@ -628,7 +628,7 @@ void SrsPlayEdge::on_all_client_stop()
// and edge is ingesting origin stream, abort it. // and edge is ingesting origin stream, abort it.
if (state == SrsEdgeStatePlay || state == SrsEdgeStateIngestConnected) { if (state == SrsEdgeStatePlay || state == SrsEdgeStateIngestConnected) {
ingester->stop(); ingester->stop();
SrsEdgeState pstate = state; SrsEdgeState pstate = state;
state = SrsEdgeStateInit; state = SrsEdgeStateInit;
srs_trace("edge change from %d to state %d (init).", pstate, state); 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 SrsPublishEdge::initialize(SrsSource* source, SrsRequest* req)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if ((ret = forwarder->initialize(source, this, req)) != ERROR_SUCCESS) { if ((ret = forwarder->initialize(source, this, req)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -700,7 +700,7 @@ int SrsPublishEdge::on_client_publish()
if (state != SrsEdgeStateInit) { if (state != SrsEdgeStateInit) {
ret = ERROR_RTMP_EDGE_PUBLISH_STATE; ret = ERROR_RTMP_EDGE_PUBLISH_STATE;
srs_error("invalid state for client to publish stream on edge. " 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; return ret;
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_EDGE_HPP #ifndef SRS_APP_EDGE_HPP
#define SRS_APP_EDGE_HPP #define SRS_APP_EDGE_HPP
/*
#include <srs_app_edge.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <srs_app_st.hpp> #include <srs_app_st.hpp>
@ -52,12 +48,12 @@ class SrsSimpleRtmpClient;
class SrsPacket; class SrsPacket;
/** /**
* the state of edge, auto machine * the state of edge, auto machine
*/ */
enum SrsEdgeState enum SrsEdgeState
{ {
SrsEdgeStateInit = 0, SrsEdgeStateInit = 0,
// for play edge // for play edge
SrsEdgeStatePlay = 100, SrsEdgeStatePlay = 100,
// play stream from origin, ingest stream // 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 enum SrsEdgeUserState
{ {
SrsEdgeUserStateInit = 0, 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 class SrsEdgeIngester : public ISrsReusableThread2Handler
{ {
private: private:
@ -146,8 +142,8 @@ private:
}; };
/** /**
* edge used to forward stream to origin. * edge used to forward stream to origin.
*/ */
class SrsEdgeForwarder : public ISrsReusableThread2Handler class SrsEdgeForwarder : public ISrsReusableThread2Handler
{ {
private: private:
@ -158,15 +154,15 @@ private:
SrsSimpleRtmpClient* sdk; SrsSimpleRtmpClient* sdk;
SrsLbRoundRobin* lb; SrsLbRoundRobin* lb;
/** /**
* we must ensure one thread one fd principle, * we must ensure one thread one fd principle,
* that is, a fd must be write/read by the one thread. * that is, a fd must be write/read by the one thread.
* the publish service thread will proxy(msg), and the edge forward 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. * will cycle(), so we use queue for cycle to send the msg of proxy.
*/ */
SrsMessageQueue* queue; 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; int send_error_code;
public: public:
SrsEdgeForwarder(); SrsEdgeForwarder();
@ -185,9 +181,9 @@ public:
}; };
/** /**
* play edge control service. * play edge control service.
* downloading edge speed-up. * downloading edge speed-up.
*/ */
class SrsPlayEdge class SrsPlayEdge
{ {
private: private:
@ -198,31 +194,31 @@ public:
virtual ~SrsPlayEdge(); virtual ~SrsPlayEdge();
public: public:
/** /**
* always use the req of source, * always use the req of source,
* for we assume all client to edge is invalid, * for we assume all client to edge is invalid,
* if auth open, edge must valid it from origin, then service it. * if auth open, edge must valid it from origin, then service it.
*/ */
virtual int initialize(SrsSource* source, SrsRequest* req); virtual int initialize(SrsSource* source, SrsRequest* req);
/** /**
* when client play stream on edge. * when client play stream on edge.
*/ */
virtual int on_client_play(); 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 void on_all_client_stop();
virtual std::string get_curr_origin(); virtual std::string get_curr_origin();
public: public:
/** /**
* when ingester start to play stream. * when ingester start to play stream.
*/ */
virtual int on_ingest_play(); virtual int on_ingest_play();
}; };
/** /**
* publish edge control service. * publish edge control service.
* uploading edge speed-up. * uploading edge speed-up.
*/ */
class SrsPublishEdge class SrsPublishEdge
{ {
private: private:
@ -237,16 +233,16 @@ public:
virtual int initialize(SrsSource* source, SrsRequest* req); virtual int initialize(SrsSource* source, SrsRequest* req);
virtual bool can_publish(); virtual bool can_publish();
/** /**
* when client publish stream on edge. * when client publish stream on edge.
*/ */
virtual int on_client_publish(); virtual int on_client_publish();
/** /**
* proxy publish stream to edge * proxy publish stream to edge
*/ */
virtual int on_proxy_publish(SrsCommonMessage* msg); virtual int on_proxy_publish(SrsCommonMessage* msg);
/** /**
* proxy unpublish stream to edge. * proxy unpublish stream to edge.
*/ */
virtual void on_proxy_unpublish(); virtual void on_proxy_unpublish();
}; };

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_empty.hpp> #include <srs_app_empty.hpp>

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_EMPTY_HPP #ifndef SRS_APP_EMPTY_HPP
#define SRS_APP_EMPTY_HPP #define SRS_APP_EMPTY_HPP
/*
#include <srs_app_empty.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#endif #endif

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_encoder.hpp> #include <srs_app_encoder.hpp>
@ -59,7 +59,7 @@ SrsEncoder::~SrsEncoder()
int SrsEncoder::on_publish(SrsRequest* req) int SrsEncoder::on_publish(SrsRequest* req)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// parse the transcode engines for vhost and app and stream. // parse the transcode engines for vhost and app and stream.
ret = parse_scope_engines(req); ret = parse_scope_engines(req);
@ -104,14 +104,14 @@ int SrsEncoder::cycle()
srs_error("transcode ffmpeg start failed. ret=%d", ret); srs_error("transcode ffmpeg start failed. ret=%d", ret);
return ret; return ret;
} }
// check ffmpeg status. // check ffmpeg status.
if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) { if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) {
srs_error("transcode ffmpeg cycle failed. ret=%d", ret); srs_error("transcode ffmpeg cycle failed. ret=%d", ret);
return ret; return ret;
} }
} }
// pithy print // pithy print
show_encode_log_message(); show_encode_log_message();
@ -122,7 +122,7 @@ void SrsEncoder::on_thread_stop()
{ {
// kill ffmpeg when finished and it alive // kill ffmpeg when finished and it alive
std::vector<SrsFFMPEG*>::iterator it; std::vector<SrsFFMPEG*>::iterator it;
for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) { for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {
SrsFFMPEG* ffmpeg = *it; SrsFFMPEG* ffmpeg = *it;
ffmpeg->stop(); ffmpeg->stop();
@ -135,7 +135,7 @@ void SrsEncoder::clear_engines()
for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) { for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {
SrsFFMPEG* ffmpeg = *it; SrsFFMPEG* ffmpeg = *it;
std::string output = ffmpeg->output(); std::string output = ffmpeg->output();
std::vector<std::string>::iterator tu_it; std::vector<std::string>::iterator tu_it;
@ -146,7 +146,7 @@ void SrsEncoder::clear_engines()
srs_freep(ffmpeg); srs_freep(ffmpeg);
} }
ffmpegs.clear(); ffmpegs.clear();
} }
@ -168,7 +168,7 @@ int SrsEncoder::parse_scope_engines(SrsRequest* req)
if ((ret = parse_ffmpeg(req, conf)) != ERROR_SUCCESS) { if ((ret = parse_ffmpeg(req, conf)) != ERROR_SUCCESS) {
if (ret != ERROR_ENCODER_LOOP) { if (ret != ERROR_ENCODER_LOOP) {
srs_error("parse vhost scope=%s transcode engines failed. " srs_error("parse vhost scope=%s transcode engines failed. "
"ret=%d", scope.c_str(), ret); "ret=%d", scope.c_str(), ret);
} }
return ret; return ret;
} }
@ -179,7 +179,7 @@ int SrsEncoder::parse_scope_engines(SrsRequest* req)
if ((ret = parse_ffmpeg(req, conf)) != ERROR_SUCCESS) { if ((ret = parse_ffmpeg(req, conf)) != ERROR_SUCCESS) {
if (ret != ERROR_ENCODER_LOOP) { if (ret != ERROR_ENCODER_LOOP) {
srs_error("parse app scope=%s transcode engines failed. " srs_error("parse app scope=%s transcode engines failed. "
"ret=%d", scope.c_str(), ret); "ret=%d", scope.c_str(), ret);
} }
return ret; return ret;
} }
@ -191,7 +191,7 @@ int SrsEncoder::parse_scope_engines(SrsRequest* req)
if ((ret = parse_ffmpeg(req, conf)) != ERROR_SUCCESS) { if ((ret = parse_ffmpeg(req, conf)) != ERROR_SUCCESS) {
if (ret != ERROR_ENCODER_LOOP) { if (ret != ERROR_ENCODER_LOOP) {
srs_error("parse stream scope=%s transcode engines failed. " srs_error("parse stream scope=%s transcode engines failed. "
"ret=%d", scope.c_str(), ret); "ret=%d", scope.c_str(), ret);
} }
return ret; return ret;
} }
@ -215,16 +215,16 @@ int SrsEncoder::parse_ffmpeg(SrsRequest* req, SrsConfDirective* conf)
// ffmpeg // ffmpeg
std::string ffmpeg_bin = _srs_config->get_transcode_ffmpeg(conf); std::string ffmpeg_bin = _srs_config->get_transcode_ffmpeg(conf);
if (ffmpeg_bin.empty()) { if (ffmpeg_bin.empty()) {
srs_trace("ignore the empty ffmpeg transcode: %s", srs_trace("ignore the empty ffmpeg transcode: %s",
conf->arg0().c_str()); conf->arg0().c_str());
return ret; return ret;
} }
// get all engines. // get all engines.
std::vector<SrsConfDirective*> engines = _srs_config->get_transcode_engines(conf); std::vector<SrsConfDirective*> engines = _srs_config->get_transcode_engines(conf);
if (engines.empty()) { if (engines.empty()) {
srs_trace("ignore the empty transcode engine: %s", srs_trace("ignore the empty transcode engine: %s",
conf->arg0().c_str()); conf->arg0().c_str());
return ret; return ret;
} }
@ -232,8 +232,8 @@ int SrsEncoder::parse_ffmpeg(SrsRequest* req, SrsConfDirective* conf)
for (int i = 0; i < (int)engines.size(); i++) { for (int i = 0; i < (int)engines.size(); i++) {
SrsConfDirective* engine = engines[i]; SrsConfDirective* engine = engines[i];
if (!_srs_config->get_engine_enabled(engine)) { if (!_srs_config->get_engine_enabled(engine)) {
srs_trace("ignore the diabled transcode engine: %s %s", srs_trace("ignore the diabled transcode engine: %s %s",
conf->arg0().c_str(), engine->arg0().c_str()); conf->arg0().c_str(), engine->arg0().c_str());
continue; continue;
} }
@ -245,7 +245,7 @@ int SrsEncoder::parse_ffmpeg(SrsRequest* req, SrsConfDirective* conf)
} }
return ret; return ret;
} }
ffmpegs.push_back(ffmpeg); 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 SrsEncoder::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsRequest* req, SrsConfDirective* engine)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
std::string input; std::string input;
// input stream, from local. // input stream, from local.
// ie. rtmp://localhost:1935/live/livestream // ie. rtmp://localhost:1935/live/livestream
@ -269,7 +269,7 @@ int SrsEncoder::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsRequest* req, SrsConfDir
input += req->vhost; input += req->vhost;
input += "/"; input += "/";
input += req->stream; input += req->stream;
// stream name: vhost/app/stream for print // stream name: vhost/app/stream for print
input_stream_name = req->vhost; input_stream_name = req->vhost;
input_stream_name += "/"; input_stream_name += "/";
@ -304,14 +304,14 @@ int SrsEncoder::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsRequest* req, SrsConfDir
} }
log_file += ".log"; log_file += ".log";
} }
// important: loop check, donot transcode again. // important: loop check, donot transcode again.
std::vector<std::string>::iterator it; std::vector<std::string>::iterator it;
it = std::find(_transcoded_url.begin(), _transcoded_url.end(), input); it = std::find(_transcoded_url.begin(), _transcoded_url.end(), input);
if (it != _transcoded_url.end()) { if (it != _transcoded_url.end()) {
ret = ERROR_ENCODER_LOOP; ret = ERROR_ENCODER_LOOP;
srs_trace("detect a loop cycle, input=%s, output=%s, ignore it. ret=%d", 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; return ret;
} }
_transcoded_url.push_back(output); _transcoded_url.push_back(output);
@ -329,12 +329,12 @@ int SrsEncoder::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsRequest* req, SrsConfDir
void SrsEncoder::show_encode_log_message() void SrsEncoder::show_encode_log_message()
{ {
pprint->elapse(); pprint->elapse();
// reportable // reportable
if (pprint->can_print()) { if (pprint->can_print()) {
// TODO: FIXME: show more info. // TODO: FIXME: show more info.
srs_trace("-> "SRS_CONSTS_LOG_ENCODER" time=%"PRId64", encoders=%d, input=%s", srs_trace("-> "SRS_CONSTS_LOG_ENCODER" time=%"PRId64", encoders=%d, input=%s",
pprint->age(), (int)ffmpegs.size(), input_stream_name.c_str()); pprint->age(), (int)ffmpegs.size(), input_stream_name.c_str());
} }
} }

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_ENCODER_HPP #ifndef SRS_APP_ENCODER_HPP
#define SRS_APP_ENCODER_HPP #define SRS_APP_ENCODER_HPP
/*
#include <srs_app_encoder.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#ifdef SRS_AUTO_TRANSCODE #ifdef SRS_AUTO_TRANSCODE
@ -42,9 +39,9 @@ class SrsPithyPrint;
class SrsFFMPEG; class SrsFFMPEG;
/** /**
* the encoder for a stream, * the encoder for a stream,
* may use multiple ffmpegs to transcode the specified stream. * may use multiple ffmpegs to transcode the specified stream.
*/ */
class SrsEncoder : public ISrsReusableThreadHandler class SrsEncoder : public ISrsReusableThreadHandler
{ {
private: private:

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_ffmpeg.hpp> #include <srs_app_ffmpeg.hpp>
@ -145,7 +145,7 @@ int SrsFFMPEG::initialize_transcode(SrsConfDirective* engine)
if (vcodec != SRS_RTMP_ENCODER_VCODEC_LIBX264) { if (vcodec != SRS_RTMP_ENCODER_VCODEC_LIBX264) {
ret = ERROR_ENCODER_VCODEC; ret = ERROR_ENCODER_VCODEC;
srs_error("invalid vcodec, must be %s, actual %s, ret=%d", 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; return ret;
} }
if (vbitrate < 0) { if (vbitrate < 0) {
@ -233,7 +233,7 @@ int SrsFFMPEG::initialize_copy()
vcodec = SRS_RTMP_ENCODER_COPY; vcodec = SRS_RTMP_ENCODER_COPY;
acodec = SRS_RTMP_ENCODER_COPY; acodec = SRS_RTMP_ENCODER_COPY;
if (_output.empty()) { if (_output.empty()) {
ret = ERROR_ENCODER_OUTPUT; ret = ERROR_ENCODER_OUTPUT;
srs_error("invalid empty output, ret=%d", ret); srs_error("invalid empty output, ret=%d", ret);

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_FFMPEG_HPP #ifndef SRS_APP_FFMPEG_HPP
#define SRS_APP_FFMPEG_HPP #define SRS_APP_FFMPEG_HPP
/*
#include <srs_app_ffmpeg.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#ifdef SRS_AUTO_FFMPEG_STUB #ifdef SRS_AUTO_FFMPEG_STUB
@ -39,9 +36,9 @@ class SrsPithyPrint;
class SrsProcess; class SrsProcess;
/** /**
* a transcode engine: ffmepg, * a transcode engine: ffmepg,
* used to transcode a stream to another. * used to transcode a stream to another.
*/ */
class SrsFFMPEG class SrsFFMPEG
{ {
private: private:

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_forward.hpp> #include <srs_app_forward.hpp>
@ -56,7 +56,7 @@ SrsForwarder::SrsForwarder(SrsOriginHub* h)
req = NULL; req = NULL;
sh_video = sh_audio = NULL; sh_video = sh_audio = NULL;
sdk = NULL; sdk = NULL;
pthread = new SrsReusableThread2("forward", this, SRS_FORWARDER_CIMS); pthread = new SrsReusableThread2("forward", this, SRS_FORWARDER_CIMS);
queue = new SrsMessageQueue(); queue = new SrsMessageQueue();
@ -130,13 +130,13 @@ int SrsForwarder::on_publish()
if (source_ep == dest_ep) { if (source_ep == dest_ep) {
ret = ERROR_SYSTEM_FORWARD_LOOP; ret = ERROR_SYSTEM_FORWARD_LOOP;
srs_warn("forward loop detected. src=%s, dest=%s, ret=%d", srs_warn("forward loop detected. src=%s, dest=%s, ret=%d",
source_ep.c_str(), dest_ep.c_str(), ret); source_ep.c_str(), dest_ep.c_str(), ret);
return ret; return ret;
} }
srs_trace("start forward %s to %s, tcUrl=%s, stream=%s", srs_trace("start forward %s to %s, tcUrl=%s, stream=%s",
source_ep.c_str(), dest_ep.c_str(), tcUrl.c_str(), source_ep.c_str(), dest_ep.c_str(), tcUrl.c_str(),
req->stream.c_str()); req->stream.c_str());
if ((ret = pthread->start()) != ERROR_SUCCESS) { if ((ret = pthread->start()) != ERROR_SUCCESS) {
srs_error("start srs thread failed. ret=%d", ret); 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 SrsForwarder::on_meta_data(SrsSharedPtrMessage* shared_metadata)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsSharedPtrMessage* metadata = shared_metadata->copy(); SrsSharedPtrMessage* metadata = shared_metadata->copy();
// TODO: FIXME: config the jitter of Forwarder. // 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 SrsForwarder::on_video(SrsSharedPtrMessage* shared_video)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsSharedPtrMessage* msg = shared_video->copy(); SrsSharedPtrMessage* msg = shared_video->copy();
// TODO: FIXME: config the jitter of Forwarder. // TODO: FIXME: config the jitter of Forwarder.
@ -271,7 +271,7 @@ int SrsForwarder::forward()
SrsPithyPrint* pprint = SrsPithyPrint::create_forwarder(); SrsPithyPrint* pprint = SrsPithyPrint::create_forwarder();
SrsAutoFree(SrsPithyPrint, pprint); SrsAutoFree(SrsPithyPrint, pprint);
SrsMessageArray msgs(SYS_MAX_FORWARD_SEND_MSGS); SrsMessageArray msgs(SYS_MAX_FORWARD_SEND_MSGS);
// update sequence header // update sequence header
@ -291,7 +291,7 @@ int SrsForwarder::forward()
while (!pthread->interrupted()) { while (!pthread->interrupted()) {
pprint->elapse(); pprint->elapse();
// read from client. // read from client.
if (true) { if (true) {
SrsCommonMessage* msg = NULL; SrsCommonMessage* msg = NULL;
@ -324,7 +324,7 @@ int SrsForwarder::forward()
srs_verbose("no packets to forward."); srs_verbose("no packets to forward.");
continue; continue;
} }
// sendout messages, all messages are freed by send_and_free_messages(). // sendout messages, all messages are freed by send_and_free_messages().
if ((ret = sdk->send_and_free_messages(msgs.msgs, count)) != ERROR_SUCCESS) { if ((ret = sdk->send_and_free_messages(msgs.msgs, count)) != ERROR_SUCCESS) {
srs_error("forwarder messages to server failed. ret=%d", ret); srs_error("forwarder messages to server failed. ret=%d", ret);

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_FORWARD_HPP #ifndef SRS_APP_FORWARD_HPP
#define SRS_APP_FORWARD_HPP #define SRS_APP_FORWARD_HPP
/*
#include <srs_app_forward.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
@ -47,8 +44,8 @@ class SrsKbps;
class SrsSimpleRtmpClient; class SrsSimpleRtmpClient;
/** /**
* forward the stream to other servers. * forward the stream to other servers.
*/ */
// TODO: FIXME: refine the error log, comments it. // TODO: FIXME: refine the error log, comments it.
class SrsForwarder : public ISrsReusableThread2Handler class SrsForwarder : public ISrsReusableThread2Handler
{ {
@ -64,9 +61,9 @@ private:
SrsRtmpJitter* jitter; SrsRtmpJitter* jitter;
SrsMessageQueue* queue; SrsMessageQueue* queue;
/** /**
* cache the sequence header for retry when slave is failed. * cache the sequence header for retry when slave is failed.
* @see https://github.com/ossrs/srs/issues/150 * @see https://github.com/ossrs/srs/issues/150
*/ */
SrsSharedPtrMessage* sh_audio; SrsSharedPtrMessage* sh_audio;
SrsSharedPtrMessage* sh_video; SrsSharedPtrMessage* sh_video;
public: public:
@ -79,19 +76,19 @@ public:
virtual int on_publish(); virtual int on_publish();
virtual void on_unpublish(); virtual void on_unpublish();
/** /**
* forward the audio packet. * forward the audio packet.
* @param shared_metadata, directly ptr, copy it if need to save it. * @param shared_metadata, directly ptr, copy it if need to save it.
*/ */
virtual int on_meta_data(SrsSharedPtrMessage* shared_metadata); virtual int on_meta_data(SrsSharedPtrMessage* shared_metadata);
/** /**
* forward the audio packet. * forward the audio packet.
* @param shared_audio, directly ptr, copy it if need to save it. * @param shared_audio, directly ptr, copy it if need to save it.
*/ */
virtual int on_audio(SrsSharedPtrMessage* shared_audio); virtual int on_audio(SrsSharedPtrMessage* shared_audio);
/** /**
* forward the video packet. * forward the video packet.
* @param shared_video, directly ptr, copy it if need to save it. * @param shared_video, directly ptr, copy it if need to save it.
*/ */
virtual int on_video(SrsSharedPtrMessage* shared_video); virtual int on_video(SrsSharedPtrMessage* shared_video);
// interface ISrsReusableThread2Handler. // interface ISrsReusableThread2Handler.
public: public:

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_fragment.hpp> #include <srs_app_fragment.hpp>

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_FRAGMENT_HPP #ifndef SRS_APP_FRAGMENT_HPP
#define SRS_APP_FRAGMENT_HPP #define SRS_APP_FRAGMENT_HPP
/*
#include <srs_app_fragment.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>

View file

@ -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 <srs_app_hds.hpp> #include <srs_app_hds.hpp>
#ifdef SRS_AUTO_HDS #ifdef SRS_AUTO_HDS
@ -52,37 +53,37 @@ static void update_box(char *start, int size)
} }
char flv_header[] = {'F', 'L', 'V', char flv_header[] = {'F', 'L', 'V',
0x01, 0x05, 0x00, 0x00, 0x00, 0x09, 0x01, 0x05, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x00}; 0x00, 0x00, 0x00, 0x00};
string serialFlv(SrsSharedPtrMessage *msg) string serialFlv(SrsSharedPtrMessage *msg)
{ {
SrsBuffer *stream = new SrsBuffer; SrsBuffer *stream = new SrsBuffer;
int size = 15 + msg->size; int size = 15 + msg->size;
char *byte = new char[size]; char *byte = new char[size];
stream->initialize(byte, size); stream->initialize(byte, size);
// tag header // tag header
long long dts = msg->timestamp; long long dts = msg->timestamp;
char type = msg->is_video() ? 0x09 : 0x08; char type = msg->is_video() ? 0x09 : 0x08;
stream->write_1bytes(type); stream->write_1bytes(type);
stream->write_3bytes(msg->size); stream->write_3bytes(msg->size);
stream->write_3bytes(dts); stream->write_3bytes(dts);
stream->write_1bytes(dts >> 24 & 0xFF); stream->write_1bytes(dts >> 24 & 0xFF);
stream->write_3bytes(0); stream->write_3bytes(0);
stream->write_bytes(msg->payload, msg->size); stream->write_bytes(msg->payload, msg->size);
// pre tag size // pre tag size
int preTagSize = msg->size + 11; int preTagSize = msg->size + 11;
stream->write_4bytes(preTagSize); stream->write_4bytes(preTagSize);
string ret(stream->data(), stream->size()); string ret(stream->data(), stream->size());
delete stream; delete stream;
delete [] byte; delete [] byte;
return ret; return ret;
} }
@ -90,20 +91,20 @@ class SrsHdsFragment
{ {
public: public:
SrsHdsFragment(SrsRequest *r) SrsHdsFragment(SrsRequest *r)
: req(r) : req(r)
, index(-1) , index(-1)
, start_time(0) , start_time(0)
, videoSh(NULL) , videoSh(NULL)
, audioSh(NULL) , audioSh(NULL)
{ {
} }
~SrsHdsFragment() ~SrsHdsFragment()
{ {
srs_freep(videoSh); srs_freep(videoSh);
srs_freep(audioSh); srs_freep(audioSh);
// clean msgs // clean msgs
list<SrsSharedPtrMessage *>::iterator iter; list<SrsSharedPtrMessage *>::iterator iter;
for (iter = msgs.begin(); iter != msgs.end(); ++iter) { for (iter = msgs.begin(); iter != msgs.end(); ++iter) {
@ -111,22 +112,22 @@ public:
srs_freep(msg); srs_freep(msg);
} }
} }
void on_video(SrsSharedPtrMessage *msg) void on_video(SrsSharedPtrMessage *msg)
{ {
SrsSharedPtrMessage *_msg = msg->copy(); SrsSharedPtrMessage *_msg = msg->copy();
msgs.push_back(_msg); msgs.push_back(_msg);
} }
void on_audio(SrsSharedPtrMessage *msg) void on_audio(SrsSharedPtrMessage *msg)
{ {
SrsSharedPtrMessage *_msg = msg->copy(); SrsSharedPtrMessage *_msg = msg->copy();
msgs.push_back(_msg); msgs.push_back(_msg);
} }
/*! /*!
flush data to disk. flush data to disk.
*/ */
int flush() int flush()
{ {
string data; string data;
@ -134,141 +135,141 @@ public:
videoSh->timestamp = start_time; videoSh->timestamp = start_time;
data.append(serialFlv(videoSh)); data.append(serialFlv(videoSh));
} }
if (audioSh) { if (audioSh) {
audioSh->timestamp = start_time; audioSh->timestamp = start_time;
data.append(serialFlv(audioSh)); data.append(serialFlv(audioSh));
} }
list<SrsSharedPtrMessage *>::iterator iter; list<SrsSharedPtrMessage *>::iterator iter;
for (iter = msgs.begin(); iter != msgs.end(); ++iter) { for (iter = msgs.begin(); iter != msgs.end(); ++iter) {
SrsSharedPtrMessage *msg = *iter; SrsSharedPtrMessage *msg = *iter;
data.append(serialFlv(msg)); data.append(serialFlv(msg));
} }
char box_header[8]; char box_header[8];
SrsBuffer ss; SrsBuffer ss;
ss.initialize(box_header, 8); ss.initialize(box_header, 8);
ss.write_4bytes(8 + data.size()); ss.write_4bytes(8 + data.size());
ss.write_string("mdat"); ss.write_string("mdat");
data = string(ss.data(), ss.size()) + data; data = string(ss.data(), ss.size()) + data;
const char *file_path = path.c_str(); const char *file_path = path.c_str();
int fd = open(file_path, O_WRONLY | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH); int fd = open(file_path, O_WRONLY | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
if (fd < 0) { if (fd < 0) {
srs_error("open fragment file failed, path=%s", file_path); srs_error("open fragment file failed, path=%s", file_path);
return -1; return -1;
} }
if (write(fd, data.data(), data.size()) != (int)data.size()) { if (write(fd, data.data(), data.size()) != (int)data.size()) {
srs_error("write fragment file failed, path=", file_path); srs_error("write fragment file failed, path=", file_path);
close(fd); close(fd);
return -1; return -1;
} }
close(fd); close(fd);
srs_trace("build fragment success=%s", file_path); srs_trace("build fragment success=%s", file_path);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
/*! /*!
calc the segment duration in milliseconds. calc the segment duration in milliseconds.
@return 0 if no msgs @return 0 if no msgs
or the last msg dts minus the first msg dts. or the last msg dts minus the first msg dts.
*/ */
int duration() int duration()
{ {
int duration_ms = 0; int duration_ms = 0;
long long first_msg_ts = 0; long long first_msg_ts = 0;
long long last_msg_ts = 0; long long last_msg_ts = 0;
if (msgs.size() >= 2) { if (msgs.size() >= 2) {
SrsSharedPtrMessage *first_msg = msgs.front(); SrsSharedPtrMessage *first_msg = msgs.front();
first_msg_ts = first_msg->timestamp; first_msg_ts = first_msg->timestamp;
SrsSharedPtrMessage *last_msg = msgs.back(); SrsSharedPtrMessage *last_msg = msgs.back();
last_msg_ts = last_msg->timestamp; last_msg_ts = last_msg->timestamp;
duration_ms = last_msg_ts - first_msg_ts; duration_ms = last_msg_ts - first_msg_ts;
} }
return duration_ms; return duration_ms;
} }
/*! /*!
set/get index set/get index
*/ */
inline void set_index(int idx) inline void set_index(int idx)
{ {
char file_path[1024] = {0}; char file_path[1024] = {0};
sprintf(file_path, "%s/%s/%sSeg1-Frag%d", _srs_config->get_hds_path(req->vhost).c_str() 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); , req->app.c_str(), req->stream.c_str(), idx);
path = file_path; path = file_path;
index = idx; index = idx;
} }
inline int get_index() inline int get_index()
{ {
return index; return index;
} }
/*! /*!
set/get start time set/get start time
*/ */
inline void set_start_time(long long st) inline void set_start_time(long long st)
{ {
start_time = st; start_time = st;
} }
inline long long get_start_time() inline long long get_start_time()
{ {
return start_time; return start_time;
} }
void set_video_sh(SrsSharedPtrMessage *msg) void set_video_sh(SrsSharedPtrMessage *msg)
{ {
srs_freep(videoSh); srs_freep(videoSh);
videoSh = msg->copy(); videoSh = msg->copy();
} }
void set_audio_sh(SrsSharedPtrMessage *msg) void set_audio_sh(SrsSharedPtrMessage *msg)
{ {
srs_freep(audioSh); srs_freep(audioSh);
audioSh = msg->copy(); audioSh = msg->copy();
} }
string fragment_path() string fragment_path()
{ {
return path; return path;
} }
private: private:
SrsRequest *req; SrsRequest *req;
list<SrsSharedPtrMessage *> msgs; list<SrsSharedPtrMessage *> msgs;
/*! /*!
the index of this fragment the index of this fragment
*/ */
int index; int index;
long long start_time; long long start_time;
SrsSharedPtrMessage *videoSh; SrsSharedPtrMessage *videoSh;
SrsSharedPtrMessage *audioSh; SrsSharedPtrMessage *audioSh;
string path; string path;
}; };
SrsHds::SrsHds() SrsHds::SrsHds()
: currentSegment(NULL) : currentSegment(NULL)
, fragment_index(1) , fragment_index(1)
, video_sh(NULL) , video_sh(NULL)
, audio_sh(NULL) , audio_sh(NULL)
, hds_req(NULL) , hds_req(NULL)
, hds_enabled(false) , hds_enabled(false)
{ {
} }
SrsHds::~SrsHds() SrsHds::~SrsHds()
@ -281,33 +282,33 @@ int SrsHds::on_publish(SrsRequest *req)
if (hds_enabled) { if (hds_enabled) {
return ret; return ret;
} }
std::string vhost = req->vhost; std::string vhost = req->vhost;
if (!_srs_config->get_hds_enabled(vhost)) { if (!_srs_config->get_hds_enabled(vhost)) {
hds_enabled = false; hds_enabled = false;
return ret; return ret;
} }
hds_enabled = true; hds_enabled = true;
hds_req = req->copy(); hds_req = req->copy();
return flush_mainfest(); return flush_mainfest();
} }
int SrsHds::on_unpublish() int SrsHds::on_unpublish()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (!hds_enabled) { if (!hds_enabled) {
return ret; return ret;
} }
hds_enabled = false; hds_enabled = false;
srs_freep(video_sh); srs_freep(video_sh);
srs_freep(audio_sh); srs_freep(audio_sh);
srs_freep(hds_req); srs_freep(hds_req);
// clean fragments // clean fragments
list<SrsHdsFragment *>::iterator iter; list<SrsHdsFragment *>::iterator iter;
for (iter = fragments.begin(); iter != fragments.end(); ++iter) { for (iter = fragments.begin(); iter != fragments.end(); ++iter) {
@ -315,41 +316,41 @@ int SrsHds::on_unpublish()
srs_freep(st); srs_freep(st);
} }
fragments.clear(); fragments.clear();
srs_freep(currentSegment); srs_freep(currentSegment);
srs_trace("HDS un-published"); srs_trace("HDS un-published");
return ret; return ret;
} }
int SrsHds::on_video(SrsSharedPtrMessage* msg) int SrsHds::on_video(SrsSharedPtrMessage* msg)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (!hds_enabled) { if (!hds_enabled) {
return ret; return ret;
} }
if (SrsFlvVideo::sh(msg->payload, msg->size)) { if (SrsFlvVideo::sh(msg->payload, msg->size)) {
srs_freep(video_sh); srs_freep(video_sh);
video_sh = msg->copy(); video_sh = msg->copy();
} }
if (!currentSegment) { if (!currentSegment) {
currentSegment = new SrsHdsFragment(hds_req); currentSegment = new SrsHdsFragment(hds_req);
currentSegment->set_index(fragment_index++); currentSegment->set_index(fragment_index++);
currentSegment->set_start_time(msg->timestamp); currentSegment->set_start_time(msg->timestamp);
if (video_sh) if (video_sh)
currentSegment->set_video_sh(video_sh); currentSegment->set_video_sh(video_sh);
if (audio_sh) if (audio_sh)
currentSegment->set_audio_sh(audio_sh); currentSegment->set_audio_sh(audio_sh);
} }
currentSegment->on_video(msg); currentSegment->on_video(msg);
double fragment_duration = _srs_config->get_hds_fragment(hds_req->vhost) * 1000; double fragment_duration = _srs_config->get_hds_fragment(hds_req->vhost) * 1000;
if (currentSegment->duration() >= fragment_duration) { if (currentSegment->duration() >= fragment_duration) {
// flush segment // flush segment
@ -357,51 +358,51 @@ int SrsHds::on_video(SrsSharedPtrMessage* msg)
srs_error("flush segment failed."); srs_error("flush segment failed.");
return ret; return ret;
} }
srs_trace("flush Segment success."); srs_trace("flush Segment success.");
fragments.push_back(currentSegment); fragments.push_back(currentSegment);
currentSegment = NULL; currentSegment = NULL;
adjust_windows(); adjust_windows();
// flush bootstrap // flush bootstrap
if ((ret = flush_bootstrap()) != ERROR_SUCCESS) { if ((ret = flush_bootstrap()) != ERROR_SUCCESS) {
srs_error("flush bootstrap failed."); srs_error("flush bootstrap failed.");
return ret; return ret;
} }
srs_trace("flush BootStrap success."); srs_trace("flush BootStrap success.");
} }
return ret; return ret;
} }
int SrsHds::on_audio(SrsSharedPtrMessage* msg) int SrsHds::on_audio(SrsSharedPtrMessage* msg)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (!hds_enabled) { if (!hds_enabled) {
return ret; return ret;
} }
if (SrsFlvAudio::sh(msg->payload, msg->size)) { if (SrsFlvAudio::sh(msg->payload, msg->size)) {
srs_freep(audio_sh); srs_freep(audio_sh);
audio_sh = msg->copy(); audio_sh = msg->copy();
} }
if (!currentSegment) { if (!currentSegment) {
currentSegment = new SrsHdsFragment(hds_req); currentSegment = new SrsHdsFragment(hds_req);
currentSegment->set_index(fragment_index++); currentSegment->set_index(fragment_index++);
currentSegment->set_start_time(msg->timestamp); currentSegment->set_start_time(msg->timestamp);
if (video_sh) if (video_sh)
currentSegment->set_video_sh(video_sh); currentSegment->set_video_sh(video_sh);
if (audio_sh) if (audio_sh)
currentSegment->set_audio_sh(audio_sh); currentSegment->set_audio_sh(audio_sh);
} }
currentSegment->on_audio(msg); currentSegment->on_audio(msg);
double fragment_duration = _srs_config->get_hds_fragment(hds_req->vhost) * 1000; double fragment_duration = _srs_config->get_hds_fragment(hds_req->vhost) * 1000;
if (currentSegment->duration() >= fragment_duration) { if (currentSegment->duration() >= fragment_duration) {
// flush segment // flush segment
@ -409,30 +410,30 @@ int SrsHds::on_audio(SrsSharedPtrMessage* msg)
srs_error("flush segment failed."); srs_error("flush segment failed.");
return ret; return ret;
} }
srs_info("flush Segment success."); srs_info("flush Segment success.");
// reset the current segment // reset the current segment
fragments.push_back(currentSegment); fragments.push_back(currentSegment);
currentSegment = NULL; currentSegment = NULL;
adjust_windows(); adjust_windows();
// flush bootstrap // flush bootstrap
if ((ret = flush_bootstrap()) != ERROR_SUCCESS) { if ((ret = flush_bootstrap()) != ERROR_SUCCESS) {
srs_error("flush bootstrap failed."); srs_error("flush bootstrap failed.");
return ret; return ret;
} }
srs_info("flush BootStrap success."); srs_info("flush BootStrap success.");
} }
return ret; return ret;
} }
int SrsHds::flush_mainfest() int SrsHds::flush_mainfest()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
char buf[1024] = {0}; char buf[1024] = {0};
sprintf(buf, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" sprintf(buf, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n\t" "<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n\t"
@ -443,21 +444,21 @@ int SrsHds::flush_mainfest()
"<media bitrate=\"0\" url=\"%s\" bootstrapInfoId=\"bootstrap0\"></media>\n" "<media bitrate=\"0\" url=\"%s\" bootstrapInfoId=\"bootstrap0\"></media>\n"
"</manifest>" "</manifest>"
, hds_req->stream.c_str(), hds_req->stream.c_str(), hds_req->stream.c_str()); , 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; string dir = _srs_config->get_hds_path(hds_req->vhost) + "/" + hds_req->app;
if ((ret = srs_create_dir_recursively(dir)) != ERROR_SUCCESS) { if ((ret = srs_create_dir_recursively(dir)) != ERROR_SUCCESS) {
srs_error("hds create dir failed. ret=%d", ret); srs_error("hds create dir failed. ret=%d", ret);
return ret; return ret;
} }
string path = dir + "/" + hds_req->stream + ".f4m"; string path = dir + "/" + hds_req->stream + ".f4m";
int fd = open(path.c_str(), O_WRONLY | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH); int fd = open(path.c_str(), O_WRONLY | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
if (fd < 0) { if (fd < 0) {
srs_error("open manifest file failed, path=%s", path.c_str()); srs_error("open manifest file failed, path=%s", path.c_str());
ret = ERROR_HDS_OPEN_F4M_FAILED; ret = ERROR_HDS_OPEN_F4M_FAILED;
return ret; return ret;
} }
int f4m_size = strlen(buf); int f4m_size = strlen(buf);
if (write(fd, buf, f4m_size) != f4m_size) { if (write(fd, buf, f4m_size) != f4m_size) {
srs_error("write manifest file failed, path=", path.c_str()); srs_error("write manifest file failed, path=", path.c_str());
@ -466,33 +467,33 @@ int SrsHds::flush_mainfest()
return ret; return ret;
} }
close(fd); close(fd);
srs_trace("build manifest success=%s", path.c_str()); srs_trace("build manifest success=%s", path.c_str());
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
int SrsHds::flush_bootstrap() int SrsHds::flush_bootstrap()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsBuffer abst; SrsBuffer abst;
int size = 1024*100; int size = 1024*100;
char *start_abst = new char[1024*100]; char *start_abst = new char[1024*100];
SrsAutoFreeA(char, start_abst); SrsAutoFreeA(char, start_abst);
int size_abst = 0; int size_abst = 0;
char *start_asrt = NULL; char *start_asrt = NULL;
int size_asrt = 0; int size_asrt = 0;
char *start_afrt = NULL; char *start_afrt = NULL;
int size_afrt = 0; int size_afrt = 0;
if ((ret = abst.initialize(start_abst, size)) != ERROR_SUCCESS) { if ((ret = abst.initialize(start_abst, size)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// @see video_file_format_spec_v10_1 // @see video_file_format_spec_v10_1
// page: 46 // page: 46
abst.write_4bytes(0); abst.write_4bytes(0);
@ -501,198 +502,198 @@ int SrsHds::flush_bootstrap()
abst.write_3bytes(0x00); // Flags always 0 abst.write_3bytes(0x00); // Flags always 0
size_abst += 12; size_abst += 12;
/*! /*!
@BootstrapinfoVersion UI32 @BootstrapinfoVersion UI32
The version number of the bootstrap information. The version number of the bootstrap information.
When the Update field is set, BootstrapinfoVersion When the Update field is set, BootstrapinfoVersion
indicates the version number that is being updated. indicates the version number that is being updated.
we assume this is the last. we assume this is the last.
*/ */
abst.write_4bytes(fragment_index - 1); // BootstrapinfoVersion abst.write_4bytes(fragment_index - 1); // BootstrapinfoVersion
abst.write_1bytes(0x20); // profile, live, update abst.write_1bytes(0x20); // profile, live, update
abst.write_4bytes(1000); // TimeScale Typically, the value is 1000, for a unit of milliseconds abst.write_4bytes(1000); // TimeScale Typically, the value is 1000, for a unit of milliseconds
size_abst += 9; size_abst += 9;
/*! /*!
The timestamp in TimeScale units of the latest available Fragment in the media presentation. The timestamp in TimeScale units of the latest available Fragment in the media presentation.
This timestamp is used to request the right fragment number. This timestamp is used to request the right fragment number.
The CurrentMedia Time can be the total duration. The CurrentMedia Time can be the total duration.
For media presentations that are not live, CurrentMediaTime can be 0. For media presentations that are not live, CurrentMediaTime can be 0.
*/ */
SrsHdsFragment *st = fragments.back(); SrsHdsFragment *st = fragments.back();
abst.write_8bytes(st->get_start_time()); abst.write_8bytes(st->get_start_time());
// SmpteTimeCodeOffset // SmpteTimeCodeOffset
abst.write_8bytes(0); abst.write_8bytes(0);
size_abst += 16; size_abst += 16;
/*! /*!
@MovieIdentifier STRING @MovieIdentifier STRING
The identifier of this presentation. The identifier of this presentation.
we write null string. we write null string.
*/ */
abst.write_1bytes(0); abst.write_1bytes(0);
size_abst += 1; size_abst += 1;
/*! /*!
@ServerEntryCount UI8 @ServerEntryCount UI8
The number of ServerEntryTable entries. The number of ServerEntryTable entries.
The minimum value is 0. The minimum value is 0.
*/ */
abst.write_1bytes(0); abst.write_1bytes(0);
size_abst += 1; size_abst += 1;
/*! /*!
@ServerEntryTable @ServerEntryTable
because we write 0 of ServerEntryCount, so this feild is ignored. because we write 0 of ServerEntryCount, so this feild is ignored.
*/ */
/*! /*!
@QualityEntryCount UI8 @QualityEntryCount UI8
The number of QualityEntryTable entries, which is The number of QualityEntryTable entries, which is
also the number of available quality levels. The also the number of available quality levels. The
minimum value is 0. Available quality levels are for, minimum value is 0. Available quality levels are for,
for example, multi bit rate files or trick files. for example, multi bit rate files or trick files.
*/ */
abst.write_1bytes(0); abst.write_1bytes(0);
size_abst += 1; size_abst += 1;
/*! /*!
@QualityEntryTable @QualityEntryTable
because we write 0 of QualityEntryCount, so this feild is ignored. because we write 0 of QualityEntryCount, so this feild is ignored.
*/ */
/*! /*!
@DrmData STRING @DrmData STRING
Null or null-terminated UTF-8 string. This string Null or null-terminated UTF-8 string. This string
holds Digital Rights Management metadata. holds Digital Rights Management metadata.
Encrypted files use this metadata to get the Encrypted files use this metadata to get the
necessary keys and licenses for decryption and play back. necessary keys and licenses for decryption and play back.
we write null string. we write null string.
*/ */
abst.write_1bytes(0); abst.write_1bytes(0);
size_abst += 1; size_abst += 1;
/*! /*!
@MetaData STRING @MetaData STRING
Null or null-terminated UTF - 8 string that holds metadata. Null or null-terminated UTF - 8 string that holds metadata.
we write null string. we write null string.
*/ */
abst.write_1bytes(0); abst.write_1bytes(0);
size_abst += 1; size_abst += 1;
/*! /*!
@SegmentRunTableCount UI8 @SegmentRunTableCount UI8
The number of entries in SegmentRunTableEntries. The number of entries in SegmentRunTableEntries.
The minimum value is 1. Typically, one table The minimum value is 1. Typically, one table
contains all segment runs. However, this count contains all segment runs. However, this count
provides the flexibility to define the segment runs provides the flexibility to define the segment runs
individually for each quality level (or trick file). individually for each quality level (or trick file).
*/ */
abst.write_1bytes(1); abst.write_1bytes(1);
size_abst += 1; size_abst += 1;
start_asrt = start_abst + size_abst; start_asrt = start_abst + size_abst;
// follows by asrt // follows by asrt
abst.write_4bytes(0); abst.write_4bytes(0);
abst.write_string("asrt"); abst.write_string("asrt");
size_asrt += 8; size_asrt += 8;
/*! /*!
@Version UI8 @Version UI8
@Flags UI24 @Flags UI24
*/ */
abst.write_4bytes(0); abst.write_4bytes(0);
size_asrt += 4; size_asrt += 4;
/*! /*!
@QualityEntryCount UI8 @QualityEntryCount UI8
The number of QualitySegmen tUrlModifiers The number of QualitySegmen tUrlModifiers
(quality level references) that follow. If 0, this (quality level references) that follow. If 0, this
Segment Run Table applies to all quality levels, Segment Run Table applies to all quality levels,
and there shall be only one Segment Run Table and there shall be only one Segment Run Table
box in the Bootstrap Info box. box in the Bootstrap Info box.
*/ */
abst.write_1bytes(0); abst.write_1bytes(0);
size_asrt += 1; size_asrt += 1;
/*! /*!
@QualitySegmentUrlModifiers @QualitySegmentUrlModifiers
ignored. ignored.
*/ */
/*! /*!
@SegmentRunEntryCount @SegmentRunEntryCount
The number of items in this The number of items in this
SegmentRunEn tryTable. The minimum value is 1. SegmentRunEn tryTable. The minimum value is 1.
*/ */
abst.write_4bytes(1); abst.write_4bytes(1);
size_asrt += 4; size_asrt += 4;
/*! /*!
@SegmentRunEntryTable @SegmentRunEntryTable
*/ */
for (int i = 0; i < 1; ++i) { for (int i = 0; i < 1; ++i) {
/*! /*!
@FirstSegment UI32 @FirstSegment UI32
The identifying number of the first segment in the run of The identifying number of the first segment in the run of
segments containing the same number of fragments. segments containing the same number of fragments.
The segment corresponding to the FirstSegment in the next The segment corresponding to the FirstSegment in the next
SEGMENTRUNENTRY will terminate this run. SEGMENTRUNENTRY will terminate this run.
*/ */
abst.write_4bytes(1); abst.write_4bytes(1);
/*! /*!
@FragmentsPerSegment UI32 @FragmentsPerSegment UI32
The number of fragments in each segment in this run. The number of fragments in each segment in this run.
*/ */
abst.write_4bytes(fragment_index - 1); abst.write_4bytes(fragment_index - 1);
size_asrt += 8; size_asrt += 8;
} }
update_box(start_asrt, size_asrt); update_box(start_asrt, size_asrt);
size_abst += size_asrt; size_abst += size_asrt;
/*! /*!
@FragmentRunTableCount UI8 @FragmentRunTableCount UI8
The number of entries in FragmentRunTable-Entries. The number of entries in FragmentRunTable-Entries.
The min i mum value is 1. The min i mum value is 1.
*/ */
abst.write_1bytes(1); abst.write_1bytes(1);
size_abst += 1; size_abst += 1;
// follows by afrt // follows by afrt
start_afrt = start_abst + size_abst; start_afrt = start_abst + size_abst;
abst.write_4bytes(0); abst.write_4bytes(0);
abst.write_string("afrt"); abst.write_string("afrt");
size_afrt += 8; size_afrt += 8;
/*! /*!
@Version UI8 @Version UI8
@Flags UI24 @Flags UI24
*/ */
abst.write_4bytes(0); abst.write_4bytes(0);
size_afrt += 4; size_afrt += 4;
/*! /*!
@TimeScale UI32 @TimeScale UI32
The number of time units per second, used in the FirstFragmentTime stamp and The number of time units per second, used in the FirstFragmentTime stamp and
Fragment Duration fields. Fragment Duration fields.
Typically, the value is 1000. Typically, the value is 1000.
*/ */
abst.write_4bytes(1000); abst.write_4bytes(1000);
size_afrt += 4; size_afrt += 4;
/*! /*!
@QualityEntryCount UI8 @QualityEntryCount UI8
The number of QualitySegment Url Modifiers The number of QualitySegment Url Modifiers
(quality level references) that follow. (quality level references) that follow.
If 0, this Fragment Run Table applies to all quality levels, If 0, this Fragment Run Table applies to all quality levels,
and there shall be only one Fragment Run Table and there shall be only one Fragment Run Table
box in the Bootstrap Info box. box in the Bootstrap Info box.
*/ */
abst.write_1bytes(0); abst.write_1bytes(0);
size_afrt += 1; size_afrt += 1;
/*! /*!
@FragmentRunEntryCount UI32 @FragmentRunEntryCount UI32
The number of items in this FragmentRunEntryTable. The number of items in this FragmentRunEntryTable.
The minimum value is 1. The minimum value is 1.
*/ */
abst.write_4bytes(fragments.size()); abst.write_4bytes(fragments.size());
size_afrt += 4; size_afrt += 4;
list<SrsHdsFragment *>::iterator iter; list<SrsHdsFragment *>::iterator iter;
for (iter = fragments.begin(); iter != fragments.end(); ++iter) { for (iter = fragments.begin(); iter != fragments.end(); ++iter) {
SrsHdsFragment *st = *iter; SrsHdsFragment *st = *iter;
@ -701,20 +702,20 @@ int SrsHds::flush_bootstrap()
abst.write_4bytes(st->duration()); abst.write_4bytes(st->duration());
size_afrt += 16; size_afrt += 16;
} }
update_box(start_afrt, size_afrt); update_box(start_afrt, size_afrt);
size_abst += size_afrt; size_abst += size_afrt;
update_box(start_abst, size_abst); update_box(start_abst, size_abst);
string path = _srs_config->get_hds_path(hds_req->vhost) + "/" + hds_req->app + "/" + hds_req->stream +".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); int fd = open(path.c_str(), O_WRONLY | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
if (fd < 0) { if (fd < 0) {
srs_error("open bootstrap file failed, path=%s", path.c_str()); srs_error("open bootstrap file failed, path=%s", path.c_str());
ret = ERROR_HDS_OPEN_BOOTSTRAP_FAILED; ret = ERROR_HDS_OPEN_BOOTSTRAP_FAILED;
return ret; return ret;
} }
if (write(fd, start_abst, size_abst) != size_abst) { if (write(fd, start_abst, size_abst) != size_abst) {
srs_error("write bootstrap file failed, path=", path.c_str()); srs_error("write bootstrap file failed, path=", path.c_str());
close(fd); close(fd);
@ -722,9 +723,9 @@ int SrsHds::flush_bootstrap()
return ret; return ret;
} }
close(fd); close(fd);
srs_trace("build bootstrap success=%s", path.c_str()); srs_trace("build bootstrap success=%s", path.c_str());
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -736,7 +737,7 @@ void SrsHds::adjust_windows()
SrsHdsFragment *fragment = *iter; SrsHdsFragment *fragment = *iter;
windows_size += fragment->duration(); windows_size += fragment->duration();
} }
double windows_size_limit = _srs_config->get_hds_window(hds_req->vhost) * 1000; double windows_size_limit = _srs_config->get_hds_window(hds_req->vhost) * 1000;
if (windows_size > windows_size_limit ) { if (windows_size > windows_size_limit ) {
SrsHdsFragment *fragment = fragments.front(); SrsHdsFragment *fragment = fragments.front();

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_HDS_HPP #ifndef SRS_APP_HDS_HPP
#define SRS_APP_HDS_HPP #define SRS_APP_HDS_HPP
@ -40,25 +40,25 @@ class SrsHds
public: public:
SrsHds(); SrsHds();
virtual ~SrsHds(); virtual ~SrsHds();
int on_publish(SrsRequest* req); int on_publish(SrsRequest* req);
int on_unpublish(); int on_unpublish();
int on_video(SrsSharedPtrMessage* msg); int on_video(SrsSharedPtrMessage* msg);
int on_audio(SrsSharedPtrMessage* msg); int on_audio(SrsSharedPtrMessage* msg);
private: private:
int flush_mainfest(); int flush_mainfest();
int flush_bootstrap(); int flush_bootstrap();
void adjust_windows(); void adjust_windows();
private: private:
std::list<SrsHdsFragment *> fragments; std::list<SrsHdsFragment *> fragments;
SrsHdsFragment *currentSegment; SrsHdsFragment *currentSegment;
int fragment_index; int fragment_index;
SrsSharedPtrMessage *video_sh; SrsSharedPtrMessage *video_sh;
SrsSharedPtrMessage *audio_sh; SrsSharedPtrMessage *audio_sh;
SrsRequest *hds_req; SrsRequest *hds_req;
bool hds_enabled; bool hds_enabled;
}; };

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_heartbeat.hpp> #include <srs_app_heartbeat.hpp>
@ -55,7 +55,7 @@ void SrsHttpHeartbeat::heartbeat()
srs_error("http uri parse hartbeart url failed. url=%s, ret=%d", url.c_str(), ret); srs_error("http uri parse hartbeart url failed. url=%s, ret=%d", url.c_str(), ret);
return; return;
} }
std::string ip = ""; std::string ip = "";
std::string device_id = _srs_config->get_heartbeat_device_id(); std::string device_id = _srs_config->get_heartbeat_device_id();
@ -86,7 +86,7 @@ void SrsHttpHeartbeat::heartbeat()
ISrsHttpMessage* msg = NULL; ISrsHttpMessage* msg = NULL;
if ((ret = http.post(uri.get_path(), req, &msg)) != ERROR_SUCCESS) { if ((ret = http.post(uri.get_path(), req, &msg)) != ERROR_SUCCESS) {
srs_info("http post hartbeart uri failed. url=%s, request=%s, ret=%d", 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; return;
} }
SrsAutoFree(ISrsHttpMessage, msg); SrsAutoFree(ISrsHttpMessage, msg);
@ -97,7 +97,7 @@ void SrsHttpHeartbeat::heartbeat()
} }
srs_info("http hook hartbeart success. url=%s, request=%s, response=%s, ret=%d", 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; return;
} }

View file

@ -1,38 +1,35 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_HEARTBEAT_HPP #ifndef SRS_APP_HEARTBEAT_HPP
#define SRS_APP_HEARTBEAT_HPP #define SRS_APP_HEARTBEAT_HPP
/*
#include <srs_app_heartbeat.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
/** /**
* the http heartbeat to api-server to notice api * the http heartbeat to api-server to notice api
* that the information of SRS. * that the information of SRS.
*/ */
class SrsHttpHeartbeat class SrsHttpHeartbeat
{ {
public: public:

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_hls.hpp> #include <srs_app_hls.hpp>
@ -262,7 +262,7 @@ int SrsHlsMuxer::initialize()
if ((ret = async->start()) != ERROR_SUCCESS) { if ((ret = async->start()) != ERROR_SUCCESS) {
return ret; return ret;
} }
return ret; return ret;
} }
@ -274,7 +274,7 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
srs_freep(req); srs_freep(req);
req = r->copy(); req = r->copy();
hls_entry_prefix = entry_prefix; hls_entry_prefix = entry_prefix;
hls_path = path; hls_path = path;
hls_ts_file = ts_file; hls_ts_file = ts_file;
@ -291,7 +291,7 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
// generate the m3u8 dir and path. // generate the m3u8 dir and path.
m3u8_url = srs_path_build_stream(m3u8_file, req->vhost, req->app, req->stream); m3u8_url = srs_path_build_stream(m3u8_file, req->vhost, req->app, req->stream);
m3u8 = path + "/" + m3u8_url; m3u8 = path + "/" + m3u8_url;
// when update config, reset the history target duration. // when update config, reset the history target duration.
max_td = (int)(fragment * _srs_config->get_hls_td_ratio(r->vhost)); 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. // when segment open, the current segment must be NULL.
srs_assert(!current); srs_assert(!current);
// load the default acodec from config. // load the default acodec from config.
SrsAudioCodecId default_acodec = SrsAudioCodecIdAAC; SrsAudioCodecId default_acodec = SrsAudioCodecIdAAC;
if (true) { if (true) {
@ -335,7 +335,7 @@ int SrsHlsMuxer::segment_open()
srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str()); srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str());
} }
} }
// load the default vcodec from config. // load the default vcodec from config.
SrsVideoCodecId default_vcodec = SrsVideoCodecIdAVC; SrsVideoCodecId default_vcodec = SrsVideoCodecIdAVC;
if (true) { if (true) {
@ -463,7 +463,7 @@ bool SrsHlsMuxer::is_segment_overflow()
// use N% deviation, to smoother. // use N% deviation, to smoother.
double deviation = hls_ts_floor? SRS_HLS_FLOOR_REAP_PERCENT * deviation_ts * hls_fragment : 0.0; 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", 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; return current->duration() >= (hls_fragment + deviation) * 1000;
} }
@ -499,7 +499,7 @@ bool SrsHlsMuxer::pure_audio()
int SrsHlsMuxer::flush_audio(SrsTsMessageCache* cache) int SrsHlsMuxer::flush_audio(SrsTsMessageCache* cache)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// if current is NULL, segment is not open, ignore the flush event. // if current is NULL, segment is not open, ignore the flush event.
if (!current) { if (!current) {
srs_warn("flush audio ignored, for segment is not open."); 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 // write success, clear and free the msg
srs_freep(cache->audio); srs_freep(cache->audio);
return ret; return ret;
} }
int SrsHlsMuxer::flush_video(SrsTsMessageCache* cache) int SrsHlsMuxer::flush_video(SrsTsMessageCache* cache)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// if current is NULL, segment is not open, ignore the flush event. // if current is NULL, segment is not open, ignore the flush event.
if (!current) { if (!current) {
srs_warn("flush video ignored, for segment is not open."); 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. // when close current segment, the current segment must not be NULL.
srs_assert(current); srs_assert(current);
// valid, add to segments if segment duration is ok // valid, add to segments if segment duration is ok
// when too small, it maybe not enough data to play. // when too small, it maybe not enough data to play.
// when too large, it maybe timestamp corrupt. // when too large, it maybe timestamp corrupt.
@ -577,7 +577,7 @@ int SrsHlsMuxer::segment_close()
{ {
return ret; return ret;
} }
// use async to call the http hooks, for it will cause thread switch. // 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) { if ((ret = async->execute(new SrsDvrAsyncCallOnHlsNotify(_srs_context->get_id(), req, current->uri))) != ERROR_SUCCESS) {
return ret; return ret;
@ -586,7 +586,7 @@ int SrsHlsMuxer::segment_close()
// close the muxer of finished segment. // close the muxer of finished segment.
srs_freep(current->tscw); srs_freep(current->tscw);
// rename from tmp to real path // rename from tmp to real path
if ((ret = current->rename()) != ERROR_SUCCESS) { if ((ret = current->rename()) != ERROR_SUCCESS) {
return ret; return ret;
@ -597,31 +597,31 @@ int SrsHlsMuxer::segment_close()
} else { } else {
// reuse current segment index. // reuse current segment index.
_sequence_no--; _sequence_no--;
srs_trace("Drop ts segment, sequence_no=%d, uri=%s, duration=%"PRId64"ms", current->sequence_no, current->uri.c_str(), current->duration()); 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 // rename from tmp to real path
if ((ret = current->unlink_tmpfile()) != ERROR_SUCCESS) { if ((ret = current->unlink_tmpfile()) != ERROR_SUCCESS) {
return ret; return ret;
} }
srs_freep(current); srs_freep(current);
} }
// shrink the segments. // shrink the segments.
segments->shrink(hls_window * 1000); segments->shrink(hls_window * 1000);
// refresh the m3u8, donot contains the removed ts // refresh the m3u8, donot contains the removed ts
ret = refresh_m3u8(); ret = refresh_m3u8();
// remove the ts file. // remove the ts file.
segments->clear_expired(hls_cleanup); segments->clear_expired(hls_cleanup);
// check ret of refresh m3u8 // check ret of refresh m3u8
if (ret != ERROR_SUCCESS) { if (ret != ERROR_SUCCESS) {
srs_error("refresh m3u8 failed. ret=%d", ret); srs_error("refresh m3u8 failed. ret=%d", ret);
return ret; return ret;
} }
return ret; return ret;
} }
@ -660,7 +660,7 @@ int SrsHlsMuxer::_refresh_m3u8(string m3u8_file)
if (segments->empty()) { if (segments->empty()) {
return ret; return ret;
} }
SrsFileWriter writer; SrsFileWriter writer;
if ((ret = writer.open(m3u8_file)) != ERROR_SUCCESS) { if ((ret = writer.open(m3u8_file)) != ERROR_SUCCESS) {
srs_error("open m3u8 file %s failed. ret=%d", m3u8_file.c_str(), ret); 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 // #EXT-X-ALLOW-CACHE:YES\n
std::stringstream ss; std::stringstream ss;
ss << "#EXTM3U" << SRS_CONSTS_LF ss << "#EXTM3U" << SRS_CONSTS_LF
<< "#EXT-X-VERSION:3" << SRS_CONSTS_LF << "#EXT-X-VERSION:3" << SRS_CONSTS_LF
<< "#EXT-X-ALLOW-CACHE:YES" << SRS_CONSTS_LF; << "#EXT-X-ALLOW-CACHE:YES" << SRS_CONSTS_LF;
srs_verbose("write m3u8 header success."); srs_verbose("write m3u8 header success.");
// #EXT-X-MEDIA-SEQUENCE:4294967295\n // #EXT-X-MEDIA-SEQUENCE:4294967295\n
@ -687,13 +687,13 @@ int SrsHlsMuxer::_refresh_m3u8(string m3u8_file)
// #EXT-X-TARGETDURATION:4294967295\n // #EXT-X-TARGETDURATION:4294967295\n
/** /**
* @see hls-m3u8-draft-pantos-http-live-streaming-12.pdf, page 25 * @see hls-m3u8-draft-pantos-http-live-streaming-12.pdf, page 25
* The Media Playlist file MUST contain an EXT-X-TARGETDURATION tag. * 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 * 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, * media segment that appears or will appear in the Playlist file,
* rounded to the nearest integer. Its value MUST NOT change. A * rounded to the nearest integer. Its value MUST NOT change. A
* typical target duration is 10 seconds. * typical target duration is 10 seconds.
*/ */
// @see https://github.com/ossrs/srs/issues/304#issuecomment-74000081 // @see https://github.com/ossrs/srs/issues/304#issuecomment-74000081
int target_duration = (int)ceil(segments->max_duration() / 1000.0); int target_duration = (int)ceil(segments->max_duration() / 1000.0);
target_duration = srs_max(target_duration, max_td); 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; ss << segment->uri << SRS_CONSTS_LF;
srs_verbose("write m3u8 segment uri success."); srs_verbose("write m3u8 segment uri success.");
} }
// write m3u8 to writer. // write m3u8 to writer.
std::string m3u8 = ss.str(); std::string m3u8 = ss.str();
if ((ret = writer.write((char*)m3u8.c_str(), (int)m3u8.length(), NULL)) != ERROR_SUCCESS) { 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 SrsHlsController::on_publish(SrsRequest* req)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
std::string vhost = req->vhost; std::string vhost = req->vhost;
std::string stream = req->stream; std::string stream = req->stream;
std::string app = req->app; std::string app = req->app;
@ -818,8 +818,8 @@ int SrsHlsController::on_publish(SrsRequest* req)
return ret; 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", 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(), 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); ts_file.c_str(), hls_aof_ratio, ts_floor, cleanup, wait_keyframe, hls_dispose);
return ret; return ret;
} }
@ -844,7 +844,7 @@ int SrsHlsController::on_sequence_header()
{ {
// TODO: support discontinuity for the same stream // TODO: support discontinuity for the same stream
// currently we reap and insert discontinity when encoder republish, // 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, // sequence header may change, for example,
// ffmpeg ingest a external rtmp stream and push to srs, // ffmpeg ingest a external rtmp stream and push to srs,
// when the sequence header changed, the stream is not republish. // 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; return ret;
} }
int SrsHlsController::write_video(SrsVideoFrame* frame, int64_t dts) int SrsHlsController::write_video(SrsVideoFrame* frame, int64_t dts)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
@ -930,7 +930,7 @@ int SrsHlsController::reap_segment()
// TODO: flush audio before or after segment? // TODO: flush audio before or after segment?
// TODO: fresh segment begin with audio or video? // TODO: fresh segment begin with audio or video?
// close current ts. // close current ts.
if ((ret = muxer->segment_close()) != ERROR_SUCCESS) { if ((ret = muxer->segment_close()) != ERROR_SUCCESS) {
srs_error("m3u8 muxer close segment failed. ret=%d", ret); srs_error("m3u8 muxer close segment failed. ret=%d", ret);
@ -968,10 +968,10 @@ SrsHls::SrsHls()
enabled = false; enabled = false;
disposable = false; disposable = false;
last_update_time = 0; last_update_time = 0;
jitter = new SrsRtmpJitter(); jitter = new SrsRtmpJitter();
controller = new SrsHlsController(); controller = new SrsHlsController();
pprint = SrsPithyPrint::create_hls(); pprint = SrsPithyPrint::create_hls();
} }
@ -1026,14 +1026,14 @@ int SrsHls::cycle()
int SrsHls::initialize(SrsOriginHub* h, SrsRequest* r) int SrsHls::initialize(SrsOriginHub* h, SrsRequest* r)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
hub = h; hub = h;
req = r; req = r;
if ((ret = controller->initialize()) != ERROR_SUCCESS) { if ((ret = controller->initialize()) != ERROR_SUCCESS) {
return ret; return ret;
} }
return ret; return ret;
} }
@ -1062,7 +1062,7 @@ int SrsHls::on_publish()
// ok, the hls can be dispose, or need to be dispose. // ok, the hls can be dispose, or need to be dispose.
disposable = true; disposable = true;
return ret; return ret;
} }
@ -1074,7 +1074,7 @@ void SrsHls::on_unpublish()
if (!enabled) { if (!enabled) {
return; return;
} }
if ((ret = controller->on_unpublish()) != ERROR_SUCCESS) { if ((ret = controller->on_unpublish()) != ERROR_SUCCESS) {
srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret); 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. // update the hls time, for hls_dispose.
last_update_time = srs_get_system_time_ms(); last_update_time = srs_get_system_time_ms();
SrsSharedPtrMessage* audio = shared_audio->copy(); SrsSharedPtrMessage* audio = shared_audio->copy();
SrsAutoFree(SrsSharedPtrMessage, audio); SrsAutoFree(SrsSharedPtrMessage, audio);
@ -1136,7 +1136,7 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format)
// update the hls time, for hls_dispose. // update the hls time, for hls_dispose.
last_update_time = srs_get_system_time_ms(); last_update_time = srs_get_system_time_ms();
SrsSharedPtrMessage* video = shared_video->copy(); SrsSharedPtrMessage* video = shared_video->copy();
SrsAutoFree(SrsSharedPtrMessage, video); SrsAutoFree(SrsSharedPtrMessage, video);
@ -1178,7 +1178,7 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format)
void SrsHls::hls_show_mux_log() void SrsHls::hls_show_mux_log()
{ {
pprint->elapse(); pprint->elapse();
if (!pprint->can_print()) { if (!pprint->can_print()) {
return; return;
} }
@ -1187,8 +1187,8 @@ void SrsHls::hls_show_mux_log()
// @see: https://github.com/ossrs/srs/issues/81#issuecomment-48100994 // @see: https://github.com/ossrs/srs/issues/81#issuecomment-48100994
// it's ok. // it's ok.
srs_trace("-> "SRS_CONSTS_LOG_HLS" time=%"PRId64", sno=%d, ts=%s, dur=%.2f, dva=%dp", 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(), pprint->age(), controller->sequence_no(), controller->ts_url().c_str(),
controller->duration(), controller->deviation()); controller->duration(), controller->deviation());
} }

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_HLS_HPP #ifndef SRS_APP_HLS_HPP
#define SRS_APP_HLS_HPP #define SRS_APP_HLS_HPP
/*
#include <srs_app_hls.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
@ -54,11 +51,11 @@ class SrsHlsSegment;
class SrsTsContext; class SrsTsContext;
/** /**
* the wrapper of m3u8 segment from specification: * the wrapper of m3u8 segment from specification:
* *
* 3.3.2. EXTINF * 3.3.2. EXTINF
* The EXTINF tag specifies the duration of a media segment. * The EXTINF tag specifies the duration of a media segment.
*/ */
class SrsHlsSegment : public SrsFragment class SrsHlsSegment : public SrsFragment
{ {
public: public:
@ -116,13 +113,13 @@ public:
}; };
/** /**
* muxer the HLS stream(m3u8 and ts files). * muxer the HLS stream(m3u8 and ts files).
* generally, the m3u8 muxer only provides methods to open/close segments, * generally, the m3u8 muxer only provides methods to open/close segments,
* to flush video/audio, without any mechenisms. * to flush video/audio, without any mechenisms.
* *
* that is, user must use HlsCache, which will control the methods of muxer, * that is, user must use HlsCache, which will control the methods of muxer,
* and provides HLS mechenisms. * and provides HLS mechenisms.
*/ */
class SrsHlsMuxer class SrsHlsMuxer
{ {
private: private:
@ -176,12 +173,12 @@ public:
virtual int deviation(); virtual int deviation();
public: public:
/** /**
* initialize the hls muxer. * initialize the hls muxer.
*/ */
virtual int initialize(); 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, virtual int update_config(SrsRequest* r, std::string entry_prefix,
std::string path, std::string m3u8_file, std::string ts_file, std::string path, std::string m3u8_file, std::string ts_file,
double fragment, double window, bool ts_floor, double aof_ratio, double fragment, double window, bool ts_floor, double aof_ratio,
@ -192,19 +189,19 @@ public:
virtual int segment_open(); virtual int segment_open();
virtual int on_sequence_header(); virtual int on_sequence_header();
/** /**
* whether segment overflow, * whether segment overflow,
* that is whether the current segment duration>=(the segment in config) * that is whether the current segment duration>=(the segment in config)
*/ */
virtual bool is_segment_overflow(); virtual bool is_segment_overflow();
/** /**
* whether wait keyframe to reap the ts. * whether wait keyframe to reap the ts.
*/ */
virtual bool wait_keyframe(); virtual bool wait_keyframe();
/** /**
* whether segment absolutely overflow, for pure audio to reap segment, * whether segment absolutely overflow, for pure audio to reap segment,
* that is whether the current segment duration>=2*(the segment in config) * that is whether the current segment duration>=2*(the segment in config)
* @see https://github.com/ossrs/srs/issues/151#issuecomment-71155184 * @see https://github.com/ossrs/srs/issues/151#issuecomment-71155184
*/ */
virtual bool is_segment_absolutely_overflow(); virtual bool is_segment_absolutely_overflow();
public: public:
/** /**
@ -223,22 +220,22 @@ private:
}; };
/** /**
* hls stream cache, * hls stream cache,
* use to cache hls stream and flush to hls muxer. * use to cache hls stream and flush to hls muxer.
* *
* when write stream to ts file: * when write stream to ts file:
* video frame will directly flush to M3u8Muxer, * video frame will directly flush to M3u8Muxer,
* audio frame need to cache, because it's small and flv tbn problem. * audio frame need to cache, because it's small and flv tbn problem.
* *
* whatever, the Hls cache used to cache video/audio, * whatever, the Hls cache used to cache video/audio,
* and flush video/audio to m3u8 muxer if needed. * and flush video/audio to m3u8 muxer if needed.
* *
* about the flv tbn problem: * about the flv tbn problem:
* flv tbn is 1/1000, ts tbn is 1/90000, * flv tbn is 1/1000, ts tbn is 1/90000,
* when timestamp convert to flv tbn, it will loose precise, * when timestamp convert to flv tbn, it will loose precise,
* so we must gather audio frame together, and recalc the timestamp @see SrsTsAacJitter, * so we must gather audio frame together, and recalc the timestamp @see SrsTsAacJitter,
* we use a aac jitter to correct the audio pts. * we use a aac jitter to correct the audio pts.
*/ */
class SrsHlsController class SrsHlsController
{ {
private: private:
@ -259,39 +256,39 @@ public:
virtual int deviation(); virtual int deviation();
public: public:
/** /**
* when publish or unpublish stream. * when publish or unpublish stream.
*/ */
virtual int on_publish(SrsRequest* req); virtual int on_publish(SrsRequest* req);
virtual int on_unpublish(); virtual int on_unpublish();
/** /**
* when get sequence header, * when get sequence header,
* must write a #EXT-X-DISCONTINUITY to m3u8. * must write a #EXT-X-DISCONTINUITY to m3u8.
* @see: hls-m3u8-draft-pantos-http-live-streaming-12.txt * @see: hls-m3u8-draft-pantos-http-live-streaming-12.txt
* @see: 3.4.11. EXT-X-DISCONTINUITY * @see: 3.4.11. EXT-X-DISCONTINUITY
*/ */
virtual int on_sequence_header(); 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); 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); virtual int write_video(SrsVideoFrame* frame, int64_t dts);
private: private:
/** /**
* reopen the muxer for a new hls segment, * reopen the muxer for a new hls segment,
* close current segment, open a new segment, * close current segment, open a new segment,
* then write the key frame to the new segment. * then write the key frame to the new segment.
* so, user must reap_segment then flush_video to hls muxer. * so, user must reap_segment then flush_video to hls muxer.
*/ */
virtual int reap_segment(); virtual int reap_segment();
}; };
/** /**
* Transmux RTMP stream to HLS(m3u8 and ts). * Transmux RTMP stream to HLS(m3u8 and ts).
* TODO: FIXME: add utest for hls. * TODO: FIXME: add utest for hls.
*/ */
class SrsHls class SrsHls
{ {
private: private:
@ -313,8 +310,8 @@ public:
virtual int cycle(); virtual int cycle();
public: public:
/** /**
* initialize the hls by handler and source. * initialize the hls by handler and source.
*/ */
virtual int initialize(SrsOriginHub* h, SrsRequest* r); virtual int initialize(SrsOriginHub* h, SrsRequest* r);
/** /**
* publish stream event, continue to write the m3u8, * publish stream event, continue to write the m3u8,
@ -323,14 +320,14 @@ public:
*/ */
virtual int on_publish(); virtual int on_publish();
/** /**
* the unpublish event, only close the muxer, donot destroy the * the unpublish event, only close the muxer, donot destroy the
* muxer, for when we continue to publish, the m3u8 will continue. * muxer, for when we continue to publish, the m3u8 will continue.
*/ */
virtual void on_unpublish(); virtual void on_unpublish();
/** /**
* mux the audio packets to ts. * mux the audio packets to ts.
* @param shared_audio, directly ptr, copy it if need to save it. * @param shared_audio, directly ptr, copy it if need to save it.
*/ */
virtual int on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format); virtual int on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format);
/** /**
* mux the video packets to ts. * mux the video packets to ts.

View file

@ -1,24 +1,24 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_hourglass.hpp> #include <srs_app_hourglass.hpp>

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_HOURGLASS_HPP #ifndef SRS_APP_HOURGLASS_HPP
#define SRS_APP_HOURGLASS_HPP #define SRS_APP_HOURGLASS_HPP
/*
#include <srs_app_hourglass.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <map> #include <map>
@ -62,7 +58,7 @@ public:
* 5. notify(type=1, time=9) * 5. notify(type=1, time=9)
* 6. notify(type=2, time=10) * 6. notify(type=2, time=10)
* this is used for server and bocar server and other manager. * this is used for server and bocar server and other manager.
* *
* Usage: * Usage:
* SrsHourGlass* hg = new SrsHourGlass(handler, 1000); * SrsHourGlass* hg = new SrsHourGlass(handler, 1000);
* hg->tick(1, 3000); * hg->tick(1, 3000);

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_http_api.hpp> #include <srs_app_http_api.hpp>
@ -151,7 +151,7 @@ int SrsGoApiRoot::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
obj->set("urls", urls); obj->set("urls", urls);
urls->set("api", SrsJsonAny::str("the api root")); urls->set("api", SrsJsonAny::str("the api root"));
return srs_api_response(w, r, obj->dumps()); 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); server->on_signal(SRS_SIGNAL_RELOAD);
return srs_api_response_code(w, r, ret); return srs_api_response_code(w, r, ret);
} }
// for rpc=query, to get the configs of server. // for rpc=query, to get the configs of server.
// @param scope the scope to query for config, it can be: // @param scope the scope to query for config, it can be:
// global, the configs belongs to the root, donot includes any sub directives. // 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 != "ff_log_dir" && scope != "srs_log_tank" && scope != "srs_log_level"
&& scope != "srs_log_file" && scope != "max_connections" && scope != "utc_time" && scope != "srs_log_file" && scope != "max_connections" && scope != "utc_time"
&& scope != "pithy_print_ms" && scope != "vhost" && scope != "dvr" && scope != "pithy_print_ms" && scope != "vhost" && scope != "dvr"
) { ) {
ret = ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED; ret = ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED;
srs_error("raw api query invalid scope=%s. ret=%d", scope.c_str(), ret); srs_error("raw api query invalid scope=%s. ret=%d", scope.c_str(), ret);
return srs_api_response_code(w, r, 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) SrsHttpApi::SrsHttpApi(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m, string cip)
: SrsConnection(cm, fd, cip) : SrsConnection(cm, fd, cip)
{ {
mux = m; mux = m;
cors = new SrsHttpCorsMux(); cors = new SrsHttpCorsMux();
@ -1360,7 +1360,7 @@ int SrsHttpApi::do_cycle()
if ((ret = parser->parse_message(skt, this, &req)) != ERROR_SUCCESS) { if ((ret = parser->parse_message(skt, this, &req)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// if SUCCESS, always NOT-NULL. // if SUCCESS, always NOT-NULL.
srs_assert(req); srs_assert(req);
@ -1372,7 +1372,7 @@ int SrsHttpApi::do_cycle()
if ((ret = process_request(&writer, req)) != ERROR_SUCCESS) { if ((ret = process_request(&writer, req)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// read all rest bytes in request body. // read all rest bytes in request body.
char buf[SRS_HTTP_READ_CACHE_BYTES]; char buf[SRS_HTTP_READ_CACHE_BYTES];
ISrsHttpResponseReader* br = req->body_reader(); ISrsHttpResponseReader* br = req->body_reader();
@ -1381,18 +1381,18 @@ int SrsHttpApi::do_cycle()
return ret; return ret;
} }
} }
// donot keep alive, disconnect it. // donot keep alive, disconnect it.
// @see https://github.com/ossrs/srs/issues/399 // @see https://github.com/ossrs/srs/issues/399
if (!req->is_keep_alive()) { if (!req->is_keep_alive()) {
break; break;
} }
} }
return ret; return ret;
} }
int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
@ -1400,8 +1400,8 @@ int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
srs_assert(hm); srs_assert(hm);
srs_trace("HTTP API %s %s, content-length=%"PRId64", chunked=%d/%d", srs_trace("HTTP API %s %s, content-length=%"PRId64", chunked=%d/%d",
r->method_str().c_str(), r->url().c_str(), r->content_length(), r->method_str().c_str(), r->url().c_str(), r->content_length(),
hm->is_chunked(), hm->is_infinite_chunked()); hm->is_chunked(), hm->is_infinite_chunked());
// use cors server mux to serve http request, which will proxy to mux. // use cors server mux to serve http request, which will proxy to mux.
if ((ret = cors->serve_http(w, r)) != ERROR_SUCCESS) { if ((ret = cors->serve_http(w, r)) != ERROR_SUCCESS) {

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_HTTP_API_HPP #ifndef SRS_APP_HTTP_API_HPP
#define SRS_APP_HTTP_API_HPP #define SRS_APP_HTTP_API_HPP
/*
#include <srs_app_http_api.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
class SrsStSocket; class SrsStSocket;

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_http_client.hpp> #include <srs_app_http_client.hpp>
@ -147,17 +147,17 @@ int SrsHttpClient::post(string path, string req, ISrsHttpMessage** ppmsg)
int SrsHttpClient::get(string path, string req, ISrsHttpMessage** ppmsg) int SrsHttpClient::get(string path, string req, ISrsHttpMessage** ppmsg)
{ {
*ppmsg = NULL; *ppmsg = NULL;
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// always set the content length. // always set the content length.
headers["Content-Length"] = srs_int2str(req.length()); headers["Content-Length"] = srs_int2str(req.length());
if ((ret = connect()) != ERROR_SUCCESS) { if ((ret = connect()) != ERROR_SUCCESS) {
srs_warn("http connect server failed. ret=%d", ret); srs_warn("http connect server failed. ret=%d", ret);
return ret; return ret;
} }
// send POST request to uri // send POST request to uri
// GET %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s // GET %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s
std::stringstream ss; std::stringstream ss;
@ -168,7 +168,7 @@ int SrsHttpClient::get(string path, string req, ISrsHttpMessage** ppmsg)
ss << key << ": " << value << SRS_HTTP_CRLF; ss << key << ": " << value << SRS_HTTP_CRLF;
} }
ss << SRS_HTTP_CRLF << req; ss << SRS_HTTP_CRLF << req;
std::string data = ss.str(); std::string data = ss.str();
if ((ret = transport->write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) { if ((ret = transport->write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) {
// Disconnect the transport when channel error, reconnect for next operation. // 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); srs_error("write http get failed. ret=%d", ret);
return ret; return ret;
} }
ISrsHttpMessage* msg = NULL; ISrsHttpMessage* msg = NULL;
if ((ret = parser->parse_message(transport, NULL, &msg)) != ERROR_SUCCESS) { if ((ret = parser->parse_message(transport, NULL, &msg)) != ERROR_SUCCESS) {
srs_error("parse http post response failed. ret=%d", ret); srs_error("parse http post response failed. ret=%d", ret);
return ret; return ret;
} }
srs_assert(msg); srs_assert(msg);
if (ppmsg) { if (ppmsg) {
*ppmsg = msg; *ppmsg = msg;
} else { } else {
srs_freep(msg); srs_freep(msg);
} }
srs_info("parse http get response success."); srs_info("parse http get response success.");
return ret; return ret;
} }

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_HTTP_CLIENT_HPP #ifndef SRS_APP_HTTP_CLIENT_HPP
#define SRS_APP_HTTP_CLIENT_HPP #define SRS_APP_HTTP_CLIENT_HPP
/*
#include <srs_app_http_client.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_http_conn.hpp> #include <srs_app_http_conn.hpp>
@ -83,7 +83,7 @@ int SrsHttpResponseWriter::final_request()
if (!header_wrote) { if (!header_wrote) {
write_header(SRS_CONSTS_HTTP_OK); write_header(SRS_CONSTS_HTTP_OK);
} }
// complete the chunked encoding. // complete the chunked encoding.
if (content_length == -1) { if (content_length == -1) {
std::stringstream ss; std::stringstream ss;
@ -266,7 +266,7 @@ int SrsHttpResponseWriter::send_header(char* data, int size)
// status_line // status_line
ss << "HTTP/1.1 " << status << " " 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 // detect content type
if (srs_go_http_body_allowd(status)) { 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) SrsHttpConn::SrsHttpConn(IConnectionManager* cm, st_netfd_t fd, ISrsHttpServeMux* m, string cip)
: SrsConnection(cm, fd, cip) : SrsConnection(cm, fd, cip)
{ {
parser = new SrsHttpParser(); parser = new SrsHttpParser();
cors = new SrsHttpCorsMux(); cors = new SrsHttpCorsMux();
@ -1128,11 +1128,11 @@ int SrsHttpConn::do_cycle()
srs_error("http initialize http parser failed. ret=%d", ret); srs_error("http initialize http parser failed. ret=%d", ret);
return ret; return ret;
} }
// set the recv timeout, for some clients never disconnect the connection. // set the recv timeout, for some clients never disconnect the connection.
// @see https://github.com/ossrs/srs/issues/398 // @see https://github.com/ossrs/srs/issues/398
skt->set_recv_timeout(SRS_HTTP_RECV_TMMS); skt->set_recv_timeout(SRS_HTTP_RECV_TMMS);
SrsRequest* last_req = NULL; SrsRequest* last_req = NULL;
SrsAutoFree(SrsRequest, last_req); SrsAutoFree(SrsRequest, last_req);
@ -1141,59 +1141,59 @@ int SrsHttpConn::do_cycle()
if ((ret = cors->initialize(http_mux, crossdomain_enabled)) != ERROR_SUCCESS) { if ((ret = cors->initialize(http_mux, crossdomain_enabled)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// process http messages. // process http messages.
while (!disposed) { while (!disposed) {
ISrsHttpMessage* req = NULL; ISrsHttpMessage* req = NULL;
// get a http message // get a http message
if ((ret = parser->parse_message(skt, this, &req)) != ERROR_SUCCESS) { if ((ret = parser->parse_message(skt, this, &req)) != ERROR_SUCCESS) {
break; break;
} }
// if SUCCESS, always NOT-NULL. // if SUCCESS, always NOT-NULL.
srs_assert(req); srs_assert(req);
// always free it in this scope. // always free it in this scope.
SrsAutoFree(ISrsHttpMessage, req); SrsAutoFree(ISrsHttpMessage, req);
// get the last request, for report the info of request on connection disconnect. // get the last request, for report the info of request on connection disconnect.
delete last_req; delete last_req;
SrsHttpMessage* hreq = dynamic_cast<SrsHttpMessage*>(req); SrsHttpMessage* hreq = dynamic_cast<SrsHttpMessage*>(req);
last_req = hreq->to_request(hreq->host()); last_req = hreq->to_request(hreq->host());
// may should discard the body. // may should discard the body.
if ((ret = on_got_http_message(req)) != ERROR_SUCCESS) { if ((ret = on_got_http_message(req)) != ERROR_SUCCESS) {
break; break;
} }
// ok, handle http request. // ok, handle http request.
SrsHttpResponseWriter writer(skt); SrsHttpResponseWriter writer(skt);
if ((ret = process_request(&writer, req)) != ERROR_SUCCESS) { if ((ret = process_request(&writer, req)) != ERROR_SUCCESS) {
break; break;
} }
// donot keep alive, disconnect it. // donot keep alive, disconnect it.
// @see https://github.com/ossrs/srs/issues/399 // @see https://github.com/ossrs/srs/issues/399
if (!req->is_keep_alive()) { if (!req->is_keep_alive()) {
break; break;
} }
} }
int disc_ret = ERROR_SUCCESS; int disc_ret = ERROR_SUCCESS;
if ((disc_ret = on_disconnect(last_req)) != 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); srs_warn("connection on disconnect peer failed, but ignore this error. disc_ret=%d, ret=%d", disc_ret, ret);
} }
return ret; return ret;
} }
int SrsHttpConn::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) int SrsHttpConn::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
srs_trace("HTTP %s %s, content-length=%"PRId64"", srs_trace("HTTP %s %s, content-length=%"PRId64"",
r->method_str().c_str(), r->url().c_str(), r->content_length()); 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. // use cors server mux to serve http request, which will proxy to http_remux.
if ((ret = cors->serve_http(w, r)) != ERROR_SUCCESS) { 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) SrsResponseOnlyHttpConn::SrsResponseOnlyHttpConn(IConnectionManager* cm, st_netfd_t fd, ISrsHttpServeMux* m, string cip)
: SrsHttpConn(cm, fd, m, cip) : SrsHttpConn(cm, fd, m, cip)
{ {
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_HTTP_CONN_HPP #ifndef SRS_APP_HTTP_CONN_HPP
#define SRS_APP_HTTP_CONN_HPP #define SRS_APP_HTTP_CONN_HPP
/*
#include <srs_app_http_conn.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <map> #include <map>
@ -128,7 +124,7 @@ public:
* initialize the response reader with buffer. * initialize the response reader with buffer.
*/ */
virtual int initialize(SrsFastStream* buffer); virtual int initialize(SrsFastStream* buffer);
// interface ISrsHttpResponseReader // interface ISrsHttpResponseReader
public: public:
virtual bool eof(); virtual bool eof();
virtual int read(char* data, int nb_data, int* nb_read); virtual int read(char* data, int nb_data, int* nb_read);
@ -173,7 +169,7 @@ private:
/** /**
* whether the body is infinite chunked. * whether the body is infinite chunked.
*/ */
bool infinite_chunked; bool infinite_chunked;
/** /**
* whether the request indicates should keep alive * whether the request indicates should keep alive
* for the http connection. * for the http connection.
@ -205,9 +201,7 @@ public:
/** /**
* set the original messages, then update the message. * set the original messages, then update the message.
*/ */
virtual int update(std::string url, bool allow_jsonp, http_parser* header, virtual int update(std::string url, bool allow_jsonp, http_parser* header, SrsFastStream* body, std::vector<SrsHttpHeaderField>& headers);
SrsFastStream* body, std::vector<SrsHttpHeaderField>& headers
);
public: public:
virtual SrsConnection* connection(); virtual SrsConnection* connection();
public: public:
@ -230,7 +224,7 @@ public:
* whether body is infinite chunked encoding. * whether body is infinite chunked encoding.
* @remark set by enter_infinite_chunked. * @remark set by enter_infinite_chunked.
*/ */
virtual bool is_infinite_chunked(); virtual bool is_infinite_chunked();
/** /**
* whether should keep the connection alive. * whether should keep the connection alive.
*/ */
@ -411,10 +405,10 @@ public:
virtual ~SrsHttpServer(); virtual ~SrsHttpServer();
public: public:
virtual int initialize(); virtual int initialize();
// ISrsHttpServeMux // ISrsHttpServeMux
public: public:
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
// http flv/ts/mp3/aac stream // http flv/ts/mp3/aac stream
public: public:
virtual int http_mount(SrsSource* s, SrsRequest* r); virtual int http_mount(SrsSource* s, SrsRequest* r);
virtual void http_unmount(SrsSource* s, SrsRequest* r); virtual void http_unmount(SrsSource* s, SrsRequest* r);

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_http_hooks.hpp> #include <srs_app_http_hooks.hpp>
@ -72,7 +72,7 @@ int SrsHttpHooks::on_connect(string url, SrsRequest* req)
obj->set("app", SrsJsonAny::str(req->app.c_str())); obj->set("app", SrsJsonAny::str(req->app.c_str()));
obj->set("tcUrl", SrsJsonAny::str(req->tcUrl.c_str())); obj->set("tcUrl", SrsJsonAny::str(req->tcUrl.c_str()));
obj->set("pageUrl", SrsJsonAny::str(req->pageUrl.c_str())); obj->set("pageUrl", SrsJsonAny::str(req->pageUrl.c_str()));
std::string data = obj->dumps(); std::string data = obj->dumps();
std::string res; std::string res;
int status_code; int status_code;
@ -80,14 +80,14 @@ int SrsHttpHooks::on_connect(string url, SrsRequest* req)
SrsHttpClient http; SrsHttpClient http;
if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) {
srs_error("http post on_connect uri failed. " srs_error("http post on_connect uri failed. "
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
return ret; return ret;
} }
srs_trace("http hook on_connect success. " srs_trace("http hook on_connect success. "
"client_id=%d, url=%s, request=%s, response=%s, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), ret);
return 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("app", SrsJsonAny::str(req->app.c_str()));
obj->set("send_bytes", SrsJsonAny::integer(send_bytes)); obj->set("send_bytes", SrsJsonAny::integer(send_bytes));
obj->set("recv_bytes", SrsJsonAny::integer(recv_bytes)); obj->set("recv_bytes", SrsJsonAny::integer(recv_bytes));
std::string data = obj->dumps(); std::string data = obj->dumps();
std::string res; std::string res;
int status_code; int status_code;
@ -116,14 +116,14 @@ void SrsHttpHooks::on_close(string url, SrsRequest* req, int64_t send_bytes, int
SrsHttpClient http; SrsHttpClient http;
if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) {
srs_warn("http post on_close uri failed, ignored. " srs_warn("http post on_close uri failed, ignored. "
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
return; return;
} }
srs_trace("http hook on_close success. " srs_trace("http hook on_close success. "
"client_id=%d, url=%s, request=%s, response=%s, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), ret);
return; return;
} }
@ -144,7 +144,7 @@ int SrsHttpHooks::on_publish(string url, SrsRequest* req)
obj->set("app", SrsJsonAny::str(req->app.c_str())); obj->set("app", SrsJsonAny::str(req->app.c_str()));
obj->set("tcUrl", SrsJsonAny::str(req->tcUrl.c_str())); obj->set("tcUrl", SrsJsonAny::str(req->tcUrl.c_str()));
obj->set("stream", SrsJsonAny::str(req->stream.c_str())); obj->set("stream", SrsJsonAny::str(req->stream.c_str()));
std::string data = obj->dumps(); std::string data = obj->dumps();
std::string res; std::string res;
int status_code; int status_code;
@ -152,14 +152,14 @@ int SrsHttpHooks::on_publish(string url, SrsRequest* req)
SrsHttpClient http; SrsHttpClient http;
if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) {
srs_error("http post on_publish uri failed. " srs_error("http post on_publish uri failed. "
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
return ret; return ret;
} }
srs_trace("http hook on_publish success. " srs_trace("http hook on_publish success. "
"client_id=%d, url=%s, request=%s, response=%s, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), ret);
return 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("vhost", SrsJsonAny::str(req->vhost.c_str()));
obj->set("app", SrsJsonAny::str(req->app.c_str())); obj->set("app", SrsJsonAny::str(req->app.c_str()));
obj->set("stream", SrsJsonAny::str(req->stream.c_str())); obj->set("stream", SrsJsonAny::str(req->stream.c_str()));
std::string data = obj->dumps(); std::string data = obj->dumps();
std::string res; std::string res;
int status_code; int status_code;
@ -187,14 +187,14 @@ void SrsHttpHooks::on_unpublish(string url, SrsRequest* req)
SrsHttpClient http; SrsHttpClient http;
if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) {
srs_warn("http post on_unpublish uri failed, ignored. " srs_warn("http post on_unpublish uri failed, ignored. "
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
return; return;
} }
srs_trace("http hook on_unpublish success. " srs_trace("http hook on_unpublish success. "
"client_id=%d, url=%s, request=%s, response=%s, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), ret);
return; return;
} }
@ -215,7 +215,7 @@ int SrsHttpHooks::on_play(string url, SrsRequest* req)
obj->set("app", SrsJsonAny::str(req->app.c_str())); obj->set("app", SrsJsonAny::str(req->app.c_str()));
obj->set("stream", SrsJsonAny::str(req->stream.c_str())); obj->set("stream", SrsJsonAny::str(req->stream.c_str()));
obj->set("pageUrl", SrsJsonAny::str(req->pageUrl.c_str())); obj->set("pageUrl", SrsJsonAny::str(req->pageUrl.c_str()));
std::string data = obj->dumps(); std::string data = obj->dumps();
std::string res; std::string res;
int status_code; int status_code;
@ -223,14 +223,14 @@ int SrsHttpHooks::on_play(string url, SrsRequest* req)
SrsHttpClient http; SrsHttpClient http;
if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) {
srs_error("http post on_play uri failed. " srs_error("http post on_play uri failed. "
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
return ret; return ret;
} }
srs_trace("http hook on_play success. " srs_trace("http hook on_play success. "
"client_id=%d, url=%s, request=%s, response=%s, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), ret);
return 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("vhost", SrsJsonAny::str(req->vhost.c_str()));
obj->set("app", SrsJsonAny::str(req->app.c_str())); obj->set("app", SrsJsonAny::str(req->app.c_str()));
obj->set("stream", SrsJsonAny::str(req->stream.c_str())); obj->set("stream", SrsJsonAny::str(req->stream.c_str()));
std::string data = obj->dumps(); std::string data = obj->dumps();
std::string res; std::string res;
int status_code; int status_code;
@ -258,14 +258,14 @@ void SrsHttpHooks::on_stop(string url, SrsRequest* req)
SrsHttpClient http; SrsHttpClient http;
if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) {
srs_warn("http post on_stop uri failed, ignored. " srs_warn("http post on_stop uri failed, ignored. "
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
return; return;
} }
srs_trace("http hook on_stop success. " srs_trace("http hook on_stop success. "
"client_id=%d, url=%s, request=%s, response=%s, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), ret);
return; 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("stream", SrsJsonAny::str(req->stream.c_str()));
obj->set("cwd", SrsJsonAny::str(cwd.c_str())); obj->set("cwd", SrsJsonAny::str(cwd.c_str()));
obj->set("file", SrsJsonAny::str(file.c_str())); obj->set("file", SrsJsonAny::str(file.c_str()));
std::string data = obj->dumps(); std::string data = obj->dumps();
std::string res; std::string res;
int status_code; int status_code;
@ -296,14 +296,14 @@ int SrsHttpHooks::on_dvr(int cid, string url, SrsRequest* req, string file)
SrsHttpClient http; SrsHttpClient http;
if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) {
srs_error("http post on_dvr uri failed, ignored. " srs_error("http post on_dvr uri failed, ignored. "
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
return ret; return ret;
} }
srs_trace("http hook on_dvr success. " srs_trace("http hook on_dvr success. "
"client_id=%d, url=%s, request=%s, response=%s, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), ret);
return 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", SrsJsonAny::str(m3u8.c_str()));
obj->set("m3u8_url", SrsJsonAny::str(m3u8_url.c_str())); obj->set("m3u8_url", SrsJsonAny::str(m3u8_url.c_str()));
obj->set("seq_no", SrsJsonAny::integer(sn)); obj->set("seq_no", SrsJsonAny::integer(sn));
std::string data = obj->dumps(); std::string data = obj->dumps();
std::string res; std::string res;
int status_code; int status_code;
@ -345,14 +345,14 @@ int SrsHttpHooks::on_hls(int cid, string url, SrsRequest* req, string file, stri
SrsHttpClient http; SrsHttpClient http;
if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) {
srs_error("http post on_hls uri failed, ignored. " srs_error("http post on_hls uri failed, ignored. "
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
return ret; return ret;
} }
srs_trace("http hook on_hls success. " srs_trace("http hook on_hls success. "
"client_id=%d, url=%s, request=%s, response=%s, ret=%d", "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, url.c_str(), data.c_str(), res.c_str(), ret);
return 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); 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", 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. // ignore any error for on_hls_notify.
ret = ERROR_SUCCESS; ret = ERROR_SUCCESS;

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_HTTP_HOOKS_HPP #ifndef SRS_APP_HTTP_HOOKS_HPP
#define SRS_APP_HTTP_HOOKS_HPP #define SRS_APP_HTTP_HOOKS_HPP
/*
#include <srs_app_http_hooks.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
@ -38,10 +35,10 @@ class SrsHttpParser;
class SrsHttpClient; class SrsHttpClient;
/** /**
* the http hooks, http callback api, * the http hooks, http callback api,
* for some event, such as on_connect, call * for some event, such as on_connect, call
* a http api(hooks). * a http api(hooks).
*/ */
class SrsHttpHooks class SrsHttpHooks
{ {
private: private:
@ -50,40 +47,40 @@ public:
virtual ~SrsHttpHooks(); virtual ~SrsHttpHooks();
public: public:
/** /**
* on_connect hook, when client connect to srs. * on_connect hook, when client connect to srs.
* @param url the api server url, to valid the client. * @param url the api server url, to valid the client.
* ignore if empty. * ignore if empty.
*/ */
static int on_connect(std::string url, SrsRequest* req); static int on_connect(std::string url, SrsRequest* req);
/** /**
* on_close hook, when client disconnect to srs, where client is valid by on_connect. * 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. * @param url the api server url, to process the event.
* ignore if empty. * ignore if empty.
*/ */
static void on_close(std::string url, SrsRequest* req, int64_t send_bytes, int64_t recv_bytes); 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 * on_publish hook, when client(encoder) start to publish stream
* @param url the api server url, to valid the client. * @param url the api server url, to valid the client.
* ignore if empty. * ignore if empty.
*/ */
static int on_publish(std::string url, SrsRequest* req); static int on_publish(std::string url, SrsRequest* req);
/** /**
* on_unpublish hook, when client(encoder) stop publish stream. * on_unpublish hook, when client(encoder) stop publish stream.
* @param url the api server url, to process the event. * @param url the api server url, to process the event.
* ignore if empty. * ignore if empty.
*/ */
static void on_unpublish(std::string url, SrsRequest* req); static void on_unpublish(std::string url, SrsRequest* req);
/** /**
* on_play hook, when client start to play stream. * on_play hook, when client start to play stream.
* @param url the api server url, to valid the client. * @param url the api server url, to valid the client.
* ignore if empty. * ignore if empty.
*/ */
static int on_play(std::string url, SrsRequest* req); static int on_play(std::string url, SrsRequest* req);
/** /**
* on_stop hook, when client stop to play the stream. * on_stop hook, when client stop to play the stream.
* @param url the api server url, to process the event. * @param url the api server url, to process the event.
* ignore if empty. * ignore if empty.
*/ */
static void on_stop(std::string url, SrsRequest* req); static void on_stop(std::string url, SrsRequest* req);
/** /**
* on_dvr hook, when reap a dvr file. * on_dvr hook, when reap a dvr file.

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_http_static.hpp> #include <srs_app_http_static.hpp>
@ -52,7 +52,7 @@ using namespace std;
#include <srs_app_server.hpp> #include <srs_app_server.hpp>
SrsVodStream::SrsVodStream(string root_dir) 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()) { if (offset > fs.filesize()) {
ret = ERROR_HTTP_REMUX_OFFSET_OVERFLOW; ret = ERROR_HTTP_REMUX_OFFSET_OVERFLOW;
srs_warn("http flv streaming %s overflow. size=%"PRId64", offset=%d, ret=%d", srs_warn("http flv streaming %s overflow. size=%"PRId64", offset=%d, ret=%d",
fullpath.c_str(), fs.filesize(), offset, ret); fullpath.c_str(), fs.filesize(), offset, ret);
return 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) { if ((ret = fs.read(sh_data, sh_size, NULL)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// seek to data offset // seek to data offset
int64_t left = fs.filesize() - offset; int64_t left = fs.filesize() - offset;
// write http header for ts. // write http header for ts.
w->header()->set_content_length((int)(sizeof(flv_header) + sh_size + left)); w->header()->set_content_length((int)(sizeof(flv_header) + sh_size + left));
w->header()->set_content_type("video/x-flv"); 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 SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int start, int end)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
srs_assert(start >= 0); srs_assert(start >= 0);
srs_assert(end == -1 || end >= 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) { if ((ret = fs.open(fullpath)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// parse -1 to whole file. // parse -1 to whole file.
if (end == -1) { if (end == -1) {
end = (int)fs.filesize(); end = (int)fs.filesize();
@ -165,21 +165,21 @@ int SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r
if (end > fs.filesize() || start > end) { if (end > fs.filesize() || start > end) {
ret = ERROR_HTTP_REMUX_OFFSET_OVERFLOW; ret = ERROR_HTTP_REMUX_OFFSET_OVERFLOW;
srs_warn("http mp4 streaming %s overflow. size=%"PRId64", offset=%d, ret=%d", srs_warn("http mp4 streaming %s overflow. size=%"PRId64", offset=%d, ret=%d",
fullpath.c_str(), fs.filesize(), start, ret); fullpath.c_str(), fs.filesize(), start, ret);
return ret; return ret;
} }
// seek to data offset, [start, end] for range. // seek to data offset, [start, end] for range.
int64_t left = end - start + 1; int64_t left = end - start + 1;
// write http header for ts. // write http header for ts.
w->header()->set_content_length(left); w->header()->set_content_length(left);
w->header()->set_content_type("video/mp4"); w->header()->set_content_type("video/mp4");
// status code 206 to make dash.as happy. // status code 206 to make dash.as happy.
w->write_header(SRS_CONSTS_HTTP_PartialContent); w->write_header(SRS_CONSTS_HTTP_PartialContent);
// response the content range header. // response the content range header.
std::stringstream content_range; std::stringstream content_range;
content_range << "bytes " << start << "-" << end << "/" << fs.filesize(); content_range << "bytes " << start << "-" << end << "/" << fs.filesize();

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_HTTP_STATIC_HPP #ifndef SRS_APP_HTTP_STATIC_HPP
#define SRS_APP_HTTP_STATIC_HPP #define SRS_APP_HTTP_STATIC_HPP
/*
#include <srs_app_http_static.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <srs_app_http_conn.hpp> #include <srs_app_http_conn.hpp>
@ -49,9 +45,9 @@ protected:
}; };
/** /**
* the http static server instance, * the http static server instance,
* serve http static file and flv/mp4 vod stream. * serve http static file and flv/mp4 vod stream.
*/ */
class SrsHttpStaticServer : virtual public ISrsReloadHandler class SrsHttpStaticServer : virtual public ISrsReloadHandler
{ {
private: private:

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_http_stream.hpp> #include <srs_app_http_stream.hpp>
@ -92,7 +92,7 @@ int SrsBufferCache::start()
int SrsBufferCache::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter) int SrsBufferCache::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (fast_cache <= 0) { if (fast_cache <= 0) {
srs_info("http: ignore dump fast cache."); srs_info("http: ignore dump fast cache.");
return ret; return ret;
@ -103,8 +103,8 @@ int SrsBufferCache::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jit
return ret; return ret;
} }
srs_trace("http: dump cache %d msgs, duration=%dms, cache=%.2fs", srs_trace("http: dump cache %d msgs, duration=%dms, cache=%.2fs",
queue->size(), queue->duration(), fast_cache); queue->size(), queue->duration(), fast_cache);
return ret; return ret;
} }
@ -127,19 +127,19 @@ int SrsBufferCache::cycle()
return ret; return ret;
} }
SrsAutoFree(SrsConsumer, consumer); SrsAutoFree(SrsConsumer, consumer);
SrsPithyPrint* pprint = SrsPithyPrint::create_http_stream_cache(); SrsPithyPrint* pprint = SrsPithyPrint::create_http_stream_cache();
SrsAutoFree(SrsPithyPrint, pprint); SrsAutoFree(SrsPithyPrint, pprint);
SrsMessageArray msgs(SRS_PERF_MW_MSGS); SrsMessageArray msgs(SRS_PERF_MW_MSGS);
// set the queue size, which used for max cache. // set the queue size, which used for max cache.
// TODO: FIXME: support reload. // TODO: FIXME: support reload.
queue->set_queue_size(fast_cache); queue->set_queue_size(fast_cache);
while (true) { while (true) {
pprint->elapse(); pprint->elapse();
// get messages from consumer. // get messages from consumer.
// each msg in msgs.msgs must be free, for the SrsMessageArray never free them. // each msg in msgs.msgs must be free, for the SrsMessageArray never free them.
int count = 0; int count = 0;
@ -156,12 +156,12 @@ int SrsBufferCache::cycle()
// ignore when nothing got. // ignore when nothing got.
continue; continue;
} }
if (pprint->can_print()) { if (pprint->can_print()) {
srs_trace("-> "SRS_CONSTS_LOG_HTTP_STREAM_CACHE" http: got %d msgs, age=%d, min=%d, mw=%d", 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); count, pprint->age(), SRS_PERF_MW_MIN_MSGS, SRS_CONSTS_RTMP_PULSE_TMMS);
} }
// free the messages. // free the messages.
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
SrsSharedPtrMessage* msg = msgs.msgs[i]; SrsSharedPtrMessage* msg = msgs.msgs[i];
@ -460,11 +460,11 @@ SrsLiveStream::~SrsLiveStream()
int SrsLiveStream::update(SrsSource* s, SrsRequest* r) int SrsLiveStream::update(SrsSource* s, SrsRequest* r)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
srs_freep(req); srs_freep(req);
source = s; source = s;
req = r->copy(); req = r->copy();
return ret; return ret;
} }
@ -506,12 +506,12 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
} }
SrsAutoFree(SrsConsumer, consumer); SrsAutoFree(SrsConsumer, consumer);
srs_verbose("http: consumer created success."); srs_verbose("http: consumer created success.");
SrsPithyPrint* pprint = SrsPithyPrint::create_http_stream(); SrsPithyPrint* pprint = SrsPithyPrint::create_http_stream();
SrsAutoFree(SrsPithyPrint, pprint); SrsAutoFree(SrsPithyPrint, pprint);
SrsMessageArray msgs(SRS_PERF_MW_MSGS); SrsMessageArray msgs(SRS_PERF_MW_MSGS);
// update the statistic when source disconveried. // update the statistic when source disconveried.
SrsStatistic* stat = SrsStatistic::instance(); SrsStatistic* stat = SrsStatistic::instance();
if ((ret = stat->on_client(_srs_context->get_id(), req, NULL, SrsRtmpConnPlay)) != ERROR_SUCCESS) { 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 #ifdef SRS_PERF_FAST_FLV_ENCODER
SrsFastFlvStreamEncoder* ffe = dynamic_cast<SrsFastFlvStreamEncoder*>(enc); SrsFastFlvStreamEncoder* ffe = dynamic_cast<SrsFastFlvStreamEncoder*>(enc);
#endif #endif
// TODO: free and erase the disabled entry after all related connections is closed. // TODO: free and erase the disabled entry after all related connections is closed.
while (entry->enabled) { while (entry->enabled) {
pprint->elapse(); pprint->elapse();
// get messages from consumer. // get messages from consumer.
// each msg in msgs.msgs must be free, for the SrsMessageArray never free them. // each msg in msgs.msgs must be free, for the SrsMessageArray never free them.
int count = 0; int count = 0;
@ -558,10 +558,10 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
// ignore when nothing got. // ignore when nothing got.
continue; continue;
} }
if (pprint->can_print()) { if (pprint->can_print()) {
srs_info("-> "SRS_CONSTS_LOG_HTTP_STREAM" http: got %d msgs, age=%d, min=%d, mw=%d", 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); count, pprint->age(), SRS_PERF_MW_MIN_MSGS, SRS_CONSTS_RTMP_PULSE_TMMS);
} }
// sendout all messages. // sendout all messages.
@ -574,7 +574,7 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
#else #else
ret = streaming_send_messages(enc, msgs.msgs, count); ret = streaming_send_messages(enc, msgs.msgs, count);
#endif #endif
// free the messages. // free the messages.
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
SrsSharedPtrMessage* msg = msgs.msgs[i]; SrsSharedPtrMessage* msg = msgs.msgs[i];
@ -622,7 +622,7 @@ SrsLiveEntry::SrsLiveEntry(std::string m)
stream = NULL; stream = NULL;
cache = NULL; cache = NULL;
req = NULL; req = NULL;
source = NULL; source = NULL;
@ -712,24 +712,24 @@ int SrsHttpStreamServer::http_mount(SrsSource* s, SrsRequest* r)
srs_info("ignore mount flv stream for disabled"); srs_info("ignore mount flv stream for disabled");
return ret; return ret;
} }
SrsLiveEntry* tmpl = tflvs[r->vhost]; SrsLiveEntry* tmpl = tflvs[r->vhost];
std::string mount = tmpl->mount; std::string mount = tmpl->mount;
// replace the vhost variable // replace the vhost variable
mount = srs_string_replace(mount, "[vhost]", r->vhost); mount = srs_string_replace(mount, "[vhost]", r->vhost);
mount = srs_string_replace(mount, "[app]", r->app); mount = srs_string_replace(mount, "[app]", r->app);
mount = srs_string_replace(mount, "[stream]", r->stream); mount = srs_string_replace(mount, "[stream]", r->stream);
// remove the default vhost mount // remove the default vhost mount
mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
entry = new SrsLiveEntry(mount); entry = new SrsLiveEntry(mount);
entry->cache = new SrsBufferCache(s, r); entry->cache = new SrsBufferCache(s, r);
entry->stream = new SrsLiveStream(s, r, entry->cache); entry->stream = new SrsLiveStream(s, r, entry->cache);
// TODO: FIXME: maybe refine the logic of http remux service. // TODO: FIXME: maybe refine the logic of http remux service.
// if user push streams followed: // if user push streams followed:
// rtmp://test.com/live/stream1 // 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 // 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. // so, need to free last request object, otherwise, it will cause memory leak.
srs_freep(tmpl->req); srs_freep(tmpl->req);
tmpl->source = s; tmpl->source = s;
tmpl->req = r->copy(); tmpl->req = r->copy();
@ -763,7 +763,7 @@ int SrsHttpStreamServer::http_mount(SrsSource* s, SrsRequest* r)
entry->stream->update(s, r); entry->stream->update(s, r);
entry->cache->update(s, r); entry->cache->update(s, r);
} }
if (entry->stream) { if (entry->stream) {
entry->stream->entry->enabled = true; entry->stream->entry->enabled = true;
return ret; return ret;
@ -775,12 +775,12 @@ int SrsHttpStreamServer::http_mount(SrsSource* s, SrsRequest* r)
void SrsHttpStreamServer::http_unmount(SrsSource* s, SrsRequest* r) void SrsHttpStreamServer::http_unmount(SrsSource* s, SrsRequest* r)
{ {
std::string sid = r->get_stream_url(); std::string sid = r->get_stream_url();
if (sflvs.find(sid) == sflvs.end()) { if (sflvs.find(sid) == sflvs.end()) {
srs_info("ignore unmount flv stream for disabled"); srs_info("ignore unmount flv stream for disabled");
return; return;
} }
SrsLiveEntry* entry = sflvs[sid]; SrsLiveEntry* entry = sflvs[sid];
entry->stream->entry->enabled = false; 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 SrsHttpStreamServer::on_reload_vhost_added(string vhost)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if ((ret = on_reload_vhost_http_remux_updated(vhost)) != ERROR_SUCCESS) { if ((ret = on_reload_vhost_http_remux_updated(vhost)) != ERROR_SUCCESS) {
return ret; return ret;
} }
return ret; return ret;
} }
int SrsHttpStreamServer::on_reload_vhost_http_remux_updated(string vhost) int SrsHttpStreamServer::on_reload_vhost_http_remux_updated(string vhost)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (tflvs.find(vhost) == tflvs.end()) { if (tflvs.find(vhost) == tflvs.end()) {
if ((ret = initialize_flv_entry(vhost)) != ERROR_SUCCESS) { if ((ret = initialize_flv_entry(vhost)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// http mount need SrsRequest and SrsSource param, only create a mapping template entry // 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. // and do mount automatically on playing http flv if this stream is a new http_remux stream.
return ret; return ret;
} }
SrsLiveEntry* tmpl = tflvs[vhost]; SrsLiveEntry* tmpl = tflvs[vhost];
SrsRequest* req = tmpl->req; SrsRequest* req = tmpl->req;
SrsSource* source = tmpl->source; SrsSource* source = tmpl->source;
if (source && req) { if (source && req) {
// cleanup the exists http remux. // cleanup the exists http remux.
http_unmount(source, req); http_unmount(source, req);
} }
if (!_srs_config->get_vhost_http_remux_enabled(vhost)) { if (!_srs_config->get_vhost_http_remux_enabled(vhost)) {
return ret; return ret;
} }
string old_tmpl_mount = tmpl->mount; string old_tmpl_mount = tmpl->mount;
string new_tmpl_mount = _srs_config->get_vhost_http_remux_mount(vhost); string new_tmpl_mount = _srs_config->get_vhost_http_remux_mount(vhost);
/** /**
* TODO: not support to reload different mount url for the time being. * TODO: not support to reload different mount url for the time being.
* if the mount is change, need more logical thing to deal with. * if the mount is change, need more logical thing to deal with.
* such as erase stream from sflvs and free all related resource. * such as erase stream from sflvs and free all related resource.
*/ */
srs_assert(old_tmpl_mount == new_tmpl_mount); srs_assert(old_tmpl_mount == new_tmpl_mount);
// do http mount directly with SrsRequest and SrsSource if stream is played already. // do http mount directly with SrsRequest and SrsSource if stream is played already.
if (req) { if (req) {
std::string sid = req->get_stream_url(); 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 // for without SrsRequest and SrsSource if stream is not played yet, do http mount automatically
// when start play this http flv stream. // when start play this http flv stream.
} }
srs_trace("vhost %s http_remux reload success", vhost.c_str()); srs_trace("vhost %s http_remux reload success", vhost.c_str());
return ret; return ret;
} }
@ -867,7 +867,7 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph)
if (ext.empty()) { if (ext.empty()) {
return ret; return ret;
} }
// find the actually request vhost. // find the actually request vhost.
SrsConfDirective* vhost = _srs_config->get_vhost(request->host()); SrsConfDirective* vhost = _srs_config->get_vhost(request->host());
if (!vhost || !_srs_config->get_vhost_enabled(vhost)) { 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, // for edge, the http stream is trigger by hstrs and mount by it,
// so we only hijack when only edge and hstrs is on. // so we only hijack when only edge and hstrs is on.
entry = it->second; entry = it->second;
// check entry and request extension. // check entry and request extension.
if (entry->is_flv()) { if (entry->is_flv()) {
if (ext != ".flv") { if (ext != ".flv") {
@ -911,7 +911,7 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph)
return ret; return ret;
} }
} }
// convert to concreate class. // convert to concreate class.
SrsHttpMessage* hreq = dynamic_cast<SrsHttpMessage*>(request); SrsHttpMessage* hreq = dynamic_cast<SrsHttpMessage*>(request);
srs_assert(hreq); srs_assert(hreq);
@ -919,7 +919,7 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph)
// hijack for entry. // hijack for entry.
SrsRequest* r = hreq->to_request(vhost->arg0()); SrsRequest* r = hreq->to_request(vhost->arg0());
SrsAutoFree(SrsRequest, r); SrsAutoFree(SrsRequest, r);
std::string sid = r->get_stream_url(); std::string sid = r->get_stream_url();
// check whether the http remux is enabled, // check whether the http remux is enabled,
// for example, user disable the http flv then reload. // for example, user disable the http flv then reload.
@ -935,18 +935,18 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph)
} }
} }
} }
SrsSource* s = NULL; SrsSource* s = NULL;
if ((ret = SrsSource::fetch_or_create(r, server, &s)) != ERROR_SUCCESS) { if ((ret = SrsSource::fetch_or_create(r, server, &s)) != ERROR_SUCCESS) {
return ret; return ret;
} }
srs_assert(s != NULL); srs_assert(s != NULL);
// create http streaming handler. // create http streaming handler.
if ((ret = http_mount(s, r)) != ERROR_SUCCESS) { if ((ret = http_mount(s, r)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// use the handler if exists. // use the handler if exists.
if (ph) { if (ph) {
if (sflvs.find(sid) != sflvs.end()) { if (sflvs.find(sid) != sflvs.end()) {
@ -958,7 +958,7 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph)
// trigger edge to fetch from origin. // trigger edge to fetch from origin.
bool vhost_is_edge = _srs_config->get_vhost_is_edge(r->vhost); 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]", 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; return ret;
} }
@ -966,7 +966,7 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph)
int SrsHttpStreamServer::initialize_flv_streaming() int SrsHttpStreamServer::initialize_flv_streaming()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// http flv live stream mount for each vhost. // http flv live stream mount for each vhost.
SrsConfDirective* root = _srs_config->get_root(); SrsConfDirective* root = _srs_config->get_root();
for (int i = 0; i < (int)root->directives.size(); i++) { for (int i = 0; i < (int)root->directives.size(); i++) {
@ -975,7 +975,7 @@ int SrsHttpStreamServer::initialize_flv_streaming()
if (!conf->is_vhost()) { if (!conf->is_vhost()) {
continue; continue;
} }
if ((ret = initialize_flv_entry(conf->arg0())) != ERROR_SUCCESS) { if ((ret = initialize_flv_entry(conf->arg0())) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -986,19 +986,16 @@ int SrsHttpStreamServer::initialize_flv_streaming()
int SrsHttpStreamServer::initialize_flv_entry(std::string vhost) int SrsHttpStreamServer::initialize_flv_entry(std::string vhost)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (!_srs_config->get_vhost_http_remux_enabled(vhost)) { if (!_srs_config->get_vhost_http_remux_enabled(vhost)) {
return ret; return ret;
} }
SrsLiveEntry* entry = new SrsLiveEntry( SrsLiveEntry* entry = new SrsLiveEntry(_srs_config->get_vhost_http_remux_mount(vhost));
_srs_config->get_vhost_http_remux_mount(vhost)
);
tflvs[vhost] = entry; tflvs[vhost] = entry;
srs_trace("http flv live stream, vhost=%s, mount=%s", srs_trace("http flv live stream, vhost=%s, mount=%s", vhost.c_str(), entry->mount.c_str());
vhost.c_str(), entry->mount.c_str());
return ret; return ret;
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_HTTP_STREAM_HPP #ifndef SRS_APP_HTTP_STREAM_HPP
#define SRS_APP_HTTP_STREAM_HPP #define SRS_APP_HTTP_STREAM_HPP
/*
#include <srs_app_http_stream.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <srs_app_http_conn.hpp> #include <srs_app_http_conn.hpp>
@ -38,10 +34,10 @@ class SrsFlvTransmuxer;
class SrsTsTransmuxer; class SrsTsTransmuxer;
/** /**
* for the srs http stream cache, * for the srs http stream cache,
* for example, the audio stream cache to make android(weixin) happy. * for example, the audio stream cache to make android(weixin) happy.
* we start a thread to shrink the queue. * we start a thread to shrink the queue.
*/ */
class SrsBufferCache : public ISrsEndlessThreadHandler class SrsBufferCache : public ISrsEndlessThreadHandler
{ {
private: 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 class ISrsBufferEncoder
{ {
public: public:
@ -73,33 +69,33 @@ public:
virtual ~ISrsBufferEncoder(); virtual ~ISrsBufferEncoder();
public: public:
/** /**
* initialize the encoder with file writer(to http response) and stream cache. * initialize the encoder with file writer(to http response) and stream cache.
* @param w the writer to write to http response. * @param w the writer to write to http response.
* @param c the stream cache for audio stream fast startup. * @param c the stream cache for audio stream fast startup.
*/ */
virtual int initialize(SrsFileWriter* w, SrsBufferCache* c) = 0; 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_audio(int64_t timestamp, char* data, int size) = 0;
virtual int write_video(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; virtual int write_metadata(int64_t timestamp, char* data, int size) = 0;
public: public:
/** /**
* for some stream, for example, mp3 and aac, the audio stream, * 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. * 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. * @return true to use gop cache of encoder; otherwise, use SrsSource.
*/ */
virtual bool has_cache() = 0; 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; 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 class SrsFlvStreamEncoder : public ISrsBufferEncoder
{ {
protected: protected:
@ -136,8 +132,8 @@ public:
#endif #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 class SrsTsStreamEncoder : public ISrsBufferEncoder
{ {
private: 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 class SrsAacStreamEncoder : public ISrsBufferEncoder
{ {
private: 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 class SrsMp3StreamEncoder : public ISrsBufferEncoder
{ {
private: private:
@ -198,8 +194,8 @@ public:
}; };
/** /**
* write stream to http response direclty. * write stream to http response direclty.
*/ */
class SrsBufferWriter : public SrsFileWriter class SrsBufferWriter : public SrsFileWriter
{ {
private: private:
@ -219,9 +215,9 @@ public:
}; };
/** /**
* the flv live stream supports access rtmp in flv over http. * the flv live stream supports access rtmp in flv over http.
* srs will remux rtmp to flv streaming. * srs will remux rtmp to flv streaming.
*/ */
class SrsLiveStream : public ISrsHttpHandler class SrsLiveStream : public ISrsHttpHandler
{ {
private: private:
@ -239,8 +235,8 @@ private:
}; };
/** /**
* the srs live entry * the srs live entry
*/ */
struct SrsLiveEntry struct SrsLiveEntry
{ {
private: private:
@ -260,7 +256,7 @@ public:
SrsBufferCache* cache; SrsBufferCache* cache;
SrsLiveEntry(std::string m); SrsLiveEntry(std::string m);
bool is_flv(); bool is_flv();
bool is_ts(); bool is_ts();
bool is_mp3(); bool is_mp3();
@ -268,12 +264,12 @@ public:
}; };
/** /**
* the http stream server instance, * the http stream server instance,
* serve http stream, for example, flv/ts/mp3/aac live stream. * serve http stream, for example, flv/ts/mp3/aac live stream.
*/ */
// TODO: Support multiple stream. // TODO: Support multiple stream.
class SrsHttpStreamServer : virtual public ISrsReloadHandler class SrsHttpStreamServer : virtual public ISrsReloadHandler
, virtual public ISrsHttpMatchHijacker , virtual public ISrsHttpMatchHijacker
{ {
private: private:
SrsServer* server; SrsServer* server;
@ -288,7 +284,7 @@ public:
virtual ~SrsHttpStreamServer(); virtual ~SrsHttpStreamServer();
public: public:
virtual int initialize(); virtual int initialize();
// http flv/ts/mp3/aac stream // http flv/ts/mp3/aac stream
public: public:
virtual int http_mount(SrsSource* s, SrsRequest* r); virtual int http_mount(SrsSource* s, SrsRequest* r);
virtual void http_unmount(SrsSource* s, SrsRequest* r); virtual void http_unmount(SrsSource* s, SrsRequest* r);

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_ingest.hpp> #include <srs_app_ingest.hpp>
@ -200,14 +200,14 @@ int SrsIngester::cycle()
srs_error("ingest ffmpeg start failed. ret=%d", ret); srs_error("ingest ffmpeg start failed. ret=%d", ret);
return ret; return ret;
} }
// check ffmpeg status. // check ffmpeg status.
if ((ret = ingester->cycle()) != ERROR_SUCCESS) { if ((ret = ingester->cycle()) != ERROR_SUCCESS) {
srs_error("ingest ffmpeg cycle failed. ret=%d", ret); srs_error("ingest ffmpeg cycle failed. ret=%d", ret);
return ret; return ret;
} }
} }
// pithy print // pithy print
show_ingest_log_message(); show_ingest_log_message();
@ -226,7 +226,7 @@ void SrsIngester::clear_engines()
SrsIngesterFFMPEG* ingester = *it; SrsIngesterFFMPEG* ingester = *it;
srs_freep(ingester); srs_freep(ingester);
} }
ingesters.clear(); 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); srs_trace("empty intput type, ingest=%s. ret=%d", ingest->arg0().c_str(), ret);
return ret; return ret;
} }
if (srs_config_ingest_is_file(input_type)) { if (srs_config_ingest_is_file(input_type)) {
std::string input_url = _srs_config->get_ingest_input_url(ingest); std::string input_url = _srs_config->get_ingest_input_url(ingest);
if (input_url.empty()) { if (input_url.empty()) {
@ -401,7 +401,7 @@ int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, S
// for file, set re. // for file, set re.
ffmpeg->set_iparams("-re"); ffmpeg->set_iparams("-re");
if ((ret = ffmpeg->initialize(input_url, output, log_file)) != ERROR_SUCCESS) { if ((ret = ffmpeg->initialize(input_url, output, log_file)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -415,14 +415,14 @@ int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, S
// for stream, no re. // for stream, no re.
ffmpeg->set_iparams(""); ffmpeg->set_iparams("");
if ((ret = ffmpeg->initialize(input_url, output, log_file)) != ERROR_SUCCESS) { if ((ret = ffmpeg->initialize(input_url, output, log_file)) != ERROR_SUCCESS) {
return ret; return ret;
} }
} else { } else {
ret = ERROR_ENCODER_INPUT_TYPE; ret = ERROR_ENCODER_INPUT_TYPE;
srs_error("invalid ingest=%s type=%s, ret=%d", srs_error("invalid ingest=%s type=%s, ret=%d",
ingest->arg0().c_str(), input_type.c_str(), ret); ingest->arg0().c_str(), input_type.c_str(), ret);
} }
// set output format to flv for RTMP // 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", srs_trace("parse success, ingest=%s, vhost=%s",
ingest->arg0().c_str(), vhost->arg0().c_str()); ingest->arg0().c_str(), vhost->arg0().c_str());
return ret; return ret;
} }
@ -451,7 +451,7 @@ int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, S
void SrsIngester::show_ingest_log_message() void SrsIngester::show_ingest_log_message()
{ {
pprint->elapse(); pprint->elapse();
if ((int)ingesters.size() <= 0) { if ((int)ingesters.size() <= 0) {
return; return;
} }
@ -463,7 +463,7 @@ void SrsIngester::show_ingest_log_message()
// reportable // reportable
if (pprint->can_print()) { if (pprint->can_print()) {
srs_trace("-> "SRS_CONSTS_LOG_INGESTER" time=%"PRId64", ingesters=%d, #%d(alive=%ds, %s)", 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(); ingester->stop();
srs_trace("reload stop ingester, vhost=%s, id=%s", vhost.c_str(), ingester->uri().c_str()); srs_trace("reload stop ingester, vhost=%s, id=%s", vhost.c_str(), ingester->uri().c_str());
srs_freep(ingester); srs_freep(ingester);
// remove the item from ingesters. // remove the item from ingesters.
it = ingesters.erase(it); it = ingesters.erase(it);
} }
return ret; return ret;
} }
@ -527,7 +527,7 @@ int SrsIngester::on_reload_ingest_removed(string vhost, string ingest_id)
ingester->stop(); ingester->stop();
srs_trace("reload stop ingester, vhost=%s, id=%s", vhost.c_str(), ingester->uri().c_str()); srs_trace("reload stop ingester, vhost=%s, id=%s", vhost.c_str(), ingester->uri().c_str());
srs_freep(ingester); srs_freep(ingester);
// remove the item from ingesters. // 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, " 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; 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 SrsIngester::on_reload_ingest_updated(string vhost, string ingest_id)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if ((ret = on_reload_ingest_removed(vhost, ingest_id)) != ERROR_SUCCESS) { if ((ret = on_reload_ingest_removed(vhost, ingest_id)) != ERROR_SUCCESS) {
return ret; return ret;
} }
if ((ret = on_reload_ingest_added(vhost, ingest_id)) != ERROR_SUCCESS) { if ((ret = on_reload_ingest_added(vhost, ingest_id)) != ERROR_SUCCESS) {
return ret; return ret;
} }
srs_trace("reload updated ingester, " 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; return ret;
} }

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_INGEST_HPP #ifndef SRS_APP_INGEST_HPP
#define SRS_APP_INGEST_HPP #define SRS_APP_INGEST_HPP
/*
#include <srs_app_ingest.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#ifdef SRS_AUTO_INGEST #ifdef SRS_AUTO_INGEST
@ -41,8 +38,8 @@ class SrsConfDirective;
class SrsPithyPrint; class SrsPithyPrint;
/** /**
* ingester ffmpeg object. * ingester ffmpeg object.
*/ */
class SrsIngesterFFMPEG class SrsIngesterFFMPEG
{ {
private: private:
@ -70,10 +67,10 @@ public:
}; };
/** /**
* ingest file/stream/device, * ingest file/stream/device,
* encode with FFMPEG(optional), * encode with FFMPEG(optional),
* push to SRS(or any RTMP server) over RTMP. * push to SRS(or any RTMP server) over RTMP.
*/ */
class SrsIngester : public ISrsReusableThreadHandler, public ISrsReloadHandler class SrsIngester : public ISrsReusableThreadHandler, public ISrsReloadHandler
{ {
private: private:

View file

@ -1,24 +1,24 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_kafka.hpp> #include <srs_app_kafka.hpp>
@ -519,7 +519,7 @@ int SrsKafkaProducer::on_before_cycle()
int SrsKafkaProducer::on_end_cycle() int SrsKafkaProducer::on_end_cycle()
{ {
st_mutex_unlock(lock); st_mutex_unlock(lock);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_KAFKA_HPP #ifndef SRS_APP_KAFKA_HPP
#define SRS_APP_KAFKA_HPP #define SRS_APP_KAFKA_HPP
/*
#include <srs_app_kafka.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <map> #include <map>

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_listener.hpp> #include <srs_app_listener.hpp>
@ -72,13 +72,13 @@ SrsUdpListener::SrsUdpListener(ISrsUdpHandler* h, string i, int p)
handler = h; handler = h;
ip = i; ip = i;
port = p; port = p;
_fd = -1; _fd = -1;
_stfd = NULL; _stfd = NULL;
nb_buf = SRS_UDP_MAX_PACKET_SIZE; nb_buf = SRS_UDP_MAX_PACKET_SIZE;
buf = new char[nb_buf]; buf = new char[nb_buf];
pthread = new SrsReusableThread("udp", this); pthread = new SrsReusableThread("udp", this);
} }
@ -86,14 +86,14 @@ SrsUdpListener::~SrsUdpListener()
{ {
// close the stfd to trigger thread to interrupted. // close the stfd to trigger thread to interrupted.
srs_close_stfd(_stfd); srs_close_stfd(_stfd);
pthread->stop(); pthread->stop();
srs_freep(pthread); srs_freep(pthread);
// st does not close it sometimes, // st does not close it sometimes,
// close it manually. // close it manually.
close(_fd); close(_fd);
srs_freepa(buf); srs_freepa(buf);
} }
@ -149,19 +149,19 @@ int SrsUdpListener::listen()
return ret; return ret;
} }
srs_verbose("create st listen thread success, ep=%s:%d", ip.c_str(), port); srs_verbose("create st listen thread success, ep=%s:%d", ip.c_str(), port);
return ret; return ret;
} }
int SrsUdpListener::cycle() int SrsUdpListener::cycle()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// TODO: FIXME: support ipv6, @see man 7 ipv6 // TODO: FIXME: support ipv6, @see man 7 ipv6
sockaddr_in from; sockaddr_in from;
int nb_from = sizeof(sockaddr_in); int nb_from = sizeof(sockaddr_in);
int nread = 0; int nread = 0;
if ((nread = st_recvfrom(_stfd, buf, nb_buf, (sockaddr*)&from, &nb_from, ST_UTIME_NO_TIMEOUT)) <= 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); srs_warn("ignore recv udp packet failed, nread=%d", nread);
return ret; return ret;
@ -171,11 +171,11 @@ int SrsUdpListener::cycle()
srs_warn("handle udp packet failed. ret=%d", ret); srs_warn("handle udp packet failed. ret=%d", ret);
return ret; return ret;
} }
if (SRS_UDP_PACKET_RECV_CYCLE_INTERVAL_MS > 0) { if (SRS_UDP_PACKET_RECV_CYCLE_INTERVAL_MS > 0) {
st_usleep(SRS_UDP_PACKET_RECV_CYCLE_INTERVAL_MS * 1000); st_usleep(SRS_UDP_PACKET_RECV_CYCLE_INTERVAL_MS * 1000);
} }
return ret; return ret;
} }
@ -184,10 +184,10 @@ SrsTcpListener::SrsTcpListener(ISrsTcpHandler* h, string i, int p)
handler = h; handler = h;
ip = i; ip = i;
port = p; port = p;
_fd = -1; _fd = -1;
_stfd = NULL; _stfd = NULL;
pthread = new SrsReusableThread("tcp", this); pthread = new SrsReusableThread("tcp", this);
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_LISTENER_HPP #ifndef SRS_APP_LISTENER_HPP
#define SRS_APP_LISTENER_HPP #define SRS_APP_LISTENER_HPP
/*
#include <srs_app_listener.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
@ -38,8 +34,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
struct sockaddr_in; struct sockaddr_in;
/** /**
* the udp packet handler. * the udp packet handler.
*/ */
class ISrsUdpHandler class ISrsUdpHandler
{ {
public: public:
@ -53,20 +49,20 @@ public:
virtual int on_stfd_change(st_netfd_t fd); virtual int on_stfd_change(st_netfd_t fd);
public: public:
/** /**
* when udp listener got a udp packet, notice server to process it. * when udp listener got a udp packet, notice server to process it.
* @param type, the client type, used to create concrete connection, * @param type, the client type, used to create concrete connection,
* for instance RTMP connection to serve client. * for instance RTMP connection to serve client.
* @param from, the udp packet from address. * @param from, the udp packet from address.
* @param buf, the udp packet bytes, user should copy if need to use. * @param buf, the udp packet bytes, user should copy if need to use.
* @param nb_buf, the size of udp packet bytes. * @param nb_buf, the size of udp packet bytes.
* @remark user should never use the buf, for it's a shared memory 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; virtual int on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) = 0;
}; };
/** /**
* the tcp connection handler. * the tcp connection handler.
*/ */
class ISrsTcpHandler class ISrsTcpHandler
{ {
public: public:
@ -74,14 +70,14 @@ public:
virtual ~ISrsTcpHandler(); virtual ~ISrsTcpHandler();
public: public:
/** /**
* when got tcp client. * when got tcp client.
*/ */
virtual int on_tcp_client(st_netfd_t stfd) = 0; 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 class SrsUdpListener : public ISrsReusableThreadHandler
{ {
private: 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 class SrsTcpListener : public ISrsReusableThreadHandler
{ {
private: private:

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_log.hpp> #include <srs_app_log.hpp>
@ -92,7 +92,7 @@ SrsFastLog::SrsFastLog()
{ {
_level = SrsLogLevel::Trace; _level = SrsLogLevel::Trace;
log_data = new char[LOG_MAX_SIZE]; log_data = new char[LOG_MAX_SIZE];
fd = -1; fd = -1;
log_to_file_tank = false; log_to_file_tank = false;
utc = false; utc = false;
@ -101,12 +101,12 @@ SrsFastLog::SrsFastLog()
SrsFastLog::~SrsFastLog() SrsFastLog::~SrsFastLog()
{ {
srs_freepa(log_data); srs_freepa(log_data);
if (fd > 0) { if (fd > 0) {
::close(fd); ::close(fd);
fd = -1; fd = -1;
} }
if (_srs_config) { if (_srs_config) {
_srs_config->unsubscribe(this); _srs_config->unsubscribe(this);
} }
@ -118,7 +118,7 @@ int SrsFastLog::initialize()
if (_srs_config) { if (_srs_config) {
_srs_config->subscribe(this); _srs_config->subscribe(this);
log_to_file_tank = _srs_config->get_log_tank_file(); log_to_file_tank = _srs_config->get_log_tank_file();
_level = srs_get_log_level(_srs_config->get_log_level()); _level = srs_get_log_level(_srs_config->get_log_level());
utc = _srs_config->get_utc_time(); 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. // we reserved 1 bytes for the new line.
size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap); size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap);
va_end(ap); va_end(ap);
write_log(fd, log_data, size, SrsLogLevel::Verbose); 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. // we reserved 1 bytes for the new line.
size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap); size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap);
va_end(ap); va_end(ap);
write_log(fd, log_data, size, SrsLogLevel::Info); 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. // we reserved 1 bytes for the new line.
size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap); size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap);
va_end(ap); va_end(ap);
write_log(fd, log_data, size, SrsLogLevel::Trace); 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. // we reserved 1 bytes for the new line.
size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap); size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap);
va_end(ap); va_end(ap);
write_log(fd, log_data, size, SrsLogLevel::Warn); 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. // we reserved 1 bytes for the new line.
size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap); size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap);
va_end(ap); va_end(ap);
// add strerror() to error msg. // add strerror() to error msg.
if (errno != 0) { if (errno != 0) {
size += snprintf(log_data + size, LOG_MAX_SIZE - size, "(%s)", strerror(errno)); size += snprintf(log_data + size, LOG_MAX_SIZE - size, "(%s)", strerror(errno));
} }
write_log(fd, log_data, size, SrsLogLevel::Error); write_log(fd, log_data, size, SrsLogLevel::Error);
} }
@ -259,18 +259,18 @@ int SrsFastLog::on_reload_log_tank()
if (!_srs_config) { if (!_srs_config) {
return ret; return ret;
} }
bool tank = log_to_file_tank; bool tank = log_to_file_tank;
log_to_file_tank = _srs_config->get_log_tank_file(); log_to_file_tank = _srs_config->get_log_tank_file();
if (tank) { if (tank) {
return ret; return ret;
} }
if (!log_to_file_tank) { if (!log_to_file_tank) {
return ret; return ret;
} }
if (fd > 0) { if (fd > 0) {
::close(fd); ::close(fd);
} }
@ -299,11 +299,11 @@ int SrsFastLog::on_reload_log_file()
if (!_srs_config) { if (!_srs_config) {
return ret; return ret;
} }
if (!log_to_file_tank) { if (!log_to_file_tank) {
return ret; return ret;
} }
if (fd > 0) { if (fd > 0) {
::close(fd); ::close(fd);
} }
@ -337,30 +337,30 @@ bool SrsFastLog::generate_header(bool error, const char* tag, int context_id, co
if (error) { if (error) {
if (tag) { if (tag) {
log_header_size = snprintf(log_data, LOG_MAX_SIZE, log_header_size = snprintf(log_data, LOG_MAX_SIZE,
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d][%d] ", "[%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), 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); level_name, tag, getpid(), context_id, errno);
} else { } else {
log_header_size = snprintf(log_data, LOG_MAX_SIZE, log_header_size = snprintf(log_data, LOG_MAX_SIZE,
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d][%d] ", "[%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), 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); level_name, getpid(), context_id, errno);
} }
} else { } else {
if (tag) { if (tag) {
log_header_size = snprintf(log_data, LOG_MAX_SIZE, log_header_size = snprintf(log_data, LOG_MAX_SIZE,
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d] ", "[%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), 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); level_name, tag, getpid(), context_id);
} else { } else {
log_header_size = snprintf(log_data, LOG_MAX_SIZE, log_header_size = snprintf(log_data, LOG_MAX_SIZE,
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d] ", "[%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), 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); level_name, getpid(), context_id);
} }
} }
if (log_header_size == -1) { if (log_header_size == -1) {
return false; 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); printf("\033[31m%.*s\033[0m", size, str_log);
} }
fflush(stdout); fflush(stdout);
return; return;
} }
@ -426,10 +426,7 @@ void SrsFastLog::open_log_file()
fd = ::open(filename.c_str(), O_RDWR | O_APPEND); fd = ::open(filename.c_str(), O_RDWR | O_APPEND);
if(fd == -1 && errno == ENOENT) { if(fd == -1 && errno == ENOENT) {
fd = open(filename.c_str(), fd = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
);
} }
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_LOG_HPP #ifndef SRS_APP_LOG_HPP
#define SRS_APP_LOG_HPP #define SRS_APP_LOG_HPP
/*
#include <srs_app_log.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <srs_app_st.hpp> #include <srs_app_st.hpp>
@ -40,9 +36,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <map> #include <map>
/** /**
* st thread context, get_id will get the st-thread id, * st thread context, get_id will get the st-thread id,
* which identify the client. * which identify the client.
*/ */
class SrsThreadContext : public ISrsThreadContext class SrsThreadContext : public ISrsThreadContext
{ {
private: private:
@ -59,13 +55,13 @@ public:
}; };
/** /**
* we use memory/disk cache and donot flush when write log. * 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. * 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. * when you want to use different level, override this classs, set the protected _level.
*/ */
class SrsFastLog : public ISrsLog, public ISrsReloadHandler class SrsFastLog : public ISrsLog, public ISrsReloadHandler
{ {
// for utest to override // for utest to override
protected: protected:
// defined in SrsLogLevel. // defined in SrsLogLevel.
int _level; int _level;

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_mpegts_udp.hpp> #include <srs_app_mpegts_udp.hpp>
@ -70,33 +70,33 @@ SrsMpegtsQueue::~SrsMpegtsQueue()
int SrsMpegtsQueue::push(SrsSharedPtrMessage* msg) int SrsMpegtsQueue::push(SrsSharedPtrMessage* msg)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// TODO: FIXME: use right way. // TODO: FIXME: use right way.
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
if (msgs.find(msg->timestamp) == msgs.end()) { if (msgs.find(msg->timestamp) == msgs.end()) {
break; break;
} }
// adjust the ts, add 1ms. // adjust the ts, add 1ms.
msg->timestamp += 1; msg->timestamp += 1;
if (i >= 5) { if (i >= 5) {
srs_warn("mpegts: free the msg for dts exists, dts=%"PRId64, msg->timestamp); srs_warn("mpegts: free the msg for dts exists, dts=%"PRId64, msg->timestamp);
srs_freep(msg); srs_freep(msg);
return ret; return ret;
} }
} }
if (msg->is_audio()) { if (msg->is_audio()) {
nb_audios++; nb_audios++;
} }
if (msg->is_video()) { if (msg->is_video()) {
nb_videos++; nb_videos++;
} }
msgs[msg->timestamp] = msg; msgs[msg->timestamp] = msg;
return ret; return ret;
} }
@ -106,23 +106,23 @@ SrsSharedPtrMessage* SrsMpegtsQueue::dequeue()
bool av_ok = nb_videos >= 2 && nb_audios >= 2; bool av_ok = nb_videos >= 2 && nb_audios >= 2;
// 100 videos about 30s, while 300 audios about 30s // 100 videos about 30s, while 300 audios about 30s
bool av_overflow = nb_videos > 100 || nb_audios > 300; bool av_overflow = nb_videos > 100 || nb_audios > 300;
if (av_ok || av_overflow) { if (av_ok || av_overflow) {
std::map<int64_t, SrsSharedPtrMessage*>::iterator it = msgs.begin(); std::map<int64_t, SrsSharedPtrMessage*>::iterator it = msgs.begin();
SrsSharedPtrMessage* msg = it->second; SrsSharedPtrMessage* msg = it->second;
msgs.erase(it); msgs.erase(it);
if (msg->is_audio()) { if (msg->is_audio()) {
nb_audios--; nb_audios--;
} }
if (msg->is_video()) { if (msg->is_video()) {
nb_videos--; nb_videos--;
} }
return msg; return msg;
} }
return NULL; return NULL;
} }
@ -147,7 +147,7 @@ SrsMpegtsOverUdp::SrsMpegtsOverUdp(SrsConfDirective* c)
SrsMpegtsOverUdp::~SrsMpegtsOverUdp() SrsMpegtsOverUdp::~SrsMpegtsOverUdp()
{ {
close(); close();
srs_freep(buffer); srs_freep(buffer);
srs_freep(stream); srs_freep(stream);
srs_freep(context); 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); std::string peer_ip = inet_ntoa(from->sin_addr);
int peer_port = ntohs(from->sin_port); int peer_port = ntohs(from->sin_port);
// append to buffer. // append to buffer.
buffer->append(buf, nb_buf); buffer->append(buf, nb_buf);
srs_info("udp: got %s:%d packet %d/%d bytes", 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); 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 SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// collect nMB data to parse in a time. // collect nMB data to parse in a time.
// TODO: FIXME: comment the following for release. // TODO: FIXME: comment the following for release.
//if (buffer->length() < 3 * 1024 * 1024) return ret; //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(); fr.close();
buffer->append(fbuf, nb_fbuf); buffer->append(fbuf, nb_fbuf);
#endif #endif
// find the sync byte of mpegts. // find the sync byte of mpegts.
char* p = buffer->bytes(); char* p = buffer->bytes();
for (int i = 0; i < buffer->length(); i++) { for (int i = 0; i < buffer->length(); i++) {
if (p[i] != 0x47) { if (p[i] != 0x47) {
continue; continue;
} }
if (i > 0) { if (i > 0) {
buffer->erase(i); buffer->erase(i);
} }
break; break;
} }
// drop ts packet when size not modulus by 188 // drop ts packet when size not modulus by 188
if (buffer->length() < SRS_TS_PACKET_SIZE) { 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()); srs_warn("udp: wait %s:%d packet %d/%d bytes", host.c_str(), port, nb_buf, buffer->length());
return ret; return ret;
} }
// use stream to parse ts packet. // use stream to parse ts packet.
int nb_packet = buffer->length() / SRS_TS_PACKET_SIZE; int nb_packet = buffer->length() / SRS_TS_PACKET_SIZE;
for (int i = 0; i < nb_packet; i++) { 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) { if ((ret = stream->initialize(p, SRS_TS_PACKET_SIZE)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// process each ts packet // process each ts packet
if ((ret = context->decode(stream, this)) != ERROR_SUCCESS) { if ((ret = context->decode(stream, this)) != ERROR_SUCCESS) {
srs_warn("mpegts: ignore parse ts packet failed. ret=%d", ret); 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 ts packet completed");
} }
srs_info("mpegts: parse udp packet completed"); srs_info("mpegts: parse udp packet completed");
// erase consumed bytes // erase consumed bytes
if (nb_packet > 0) { if (nb_packet > 0) {
buffer->erase(nb_packet * SRS_TS_PACKET_SIZE); buffer->erase(nb_packet * SRS_TS_PACKET_SIZE);
} }
return ret; return ret;
} }
int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg) int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
pprint->elapse(); pprint->elapse();
// about the bytes of msg, specified by elementary stream which indicates by PES_packet_data_byte and stream_id // 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, // 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 // 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). // 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). // 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 // 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 // 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 // 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_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_length minus the number of bytes between the last byte of the PES_packet_length field and the first
// PES_packet_data_byte. // PES_packet_data_byte.
// //
// In the case of a private_stream_1, private_stream_2, ECM_stream, or EMM_stream, the contents of the // 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_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 // 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 "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 // 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 // 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. // 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. // about the stream_id table, define in Table 2-18 "C Stream_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 52.
// //
// 110x xxxx // 110x xxxx
// ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC
// 14496-3 audio stream number x xxxx // 14496-3 audio stream number x xxxx
// ((sid >> 5) & 0x07) == SrsTsPESStreamIdAudio // ((sid >> 5) & 0x07) == SrsTsPESStreamIdAudio
// //
// 1110 xxxx // 1110 xxxx
// ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC // ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC
// 14496-2 video stream number xxxx // 14496-2 video stream number xxxx
// ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo // ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo
if (pprint->can_print()) { 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)", 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->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->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->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number());
} }
// When the audio SID is private stream 1, we use common audio. // 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) { if (msg->channel->apply == SrsTsPidApplyAudio && msg->sid == SrsTsPESStreamIdPrivateStream1) {
msg->sid = SrsTsPESStreamIdAudioCommon; msg->sid = SrsTsPESStreamIdAudioCommon;
} }
// when not audio/video, or not adts/annexb format, donot support. // when not audio/video, or not adts/annexb format, donot support.
if (msg->stream_number() != 0) { if (msg->stream_number() != 0) {
ret = ERROR_STREAM_CASTER_TS_ES; ret = ERROR_STREAM_CASTER_TS_ES;
srs_error("mpegts: unsupported stream format, sid=%#x(%s-%d). ret=%d", 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); msg->sid, msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number(), ret);
return ret; return ret;
} }
// check supported codec // check supported codec
if (msg->channel->stream != SrsTsStreamVideoH264 && msg->channel->stream != SrsTsStreamAudioAAC) { if (msg->channel->stream != SrsTsStreamVideoH264 && msg->channel->stream != SrsTsStreamAudioAAC) {
ret = ERROR_STREAM_CASTER_TS_CODEC; ret = ERROR_STREAM_CASTER_TS_CODEC;
srs_error("mpegts: unsupported stream codec=%d. ret=%d", msg->channel->stream, ret); srs_error("mpegts: unsupported stream codec=%d. ret=%d", msg->channel->stream, ret);
return ret; return ret;
} }
// parse the stream. // parse the stream.
SrsBuffer avs; SrsBuffer avs;
if ((ret = avs.initialize(msg->payload->bytes(), msg->payload->length())) != ERROR_SUCCESS) { if ((ret = avs.initialize(msg->payload->bytes(), msg->payload->length())) != ERROR_SUCCESS) {
srs_error("mpegts: initialize av stream failed. ret=%d", ret); srs_error("mpegts: initialize av stream failed. ret=%d", ret);
return ret; return ret;
} }
// publish audio or video. // publish audio or video.
if (msg->channel->stream == SrsTsStreamVideoH264) { if (msg->channel->stream == SrsTsStreamVideoH264) {
return on_ts_video(msg, &avs); return on_ts_video(msg, &avs);
@ -334,7 +334,7 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
if (msg->channel->stream == SrsTsStreamAudioAAC) { if (msg->channel->stream == SrsTsStreamAudioAAC) {
return on_ts_audio(msg, &avs); return on_ts_audio(msg, &avs);
} }
// TODO: FIXME: implements it. // TODO: FIXME: implements it.
return ret; return ret;
} }
@ -342,12 +342,12 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsBuffer* avs) int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsBuffer* avs)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// ensure rtmp connected. // ensure rtmp connected.
if ((ret = connect()) != ERROR_SUCCESS) { if ((ret = connect()) != ERROR_SUCCESS) {
return ret; return ret;
} }
// ts tbn to flv tbn. // ts tbn to flv tbn.
uint32_t dts = (uint32_t)(msg->dts / 90); uint32_t dts = (uint32_t)(msg->dts / 90);
uint32_t pts = (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) { if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) {
continue; continue;
} }
// for sps // for sps
if (avc->is_sps(frame, frame_size)) { if (avc->is_sps(frame, frame_size)) {
std::string sps; std::string sps;
if ((ret = avc->sps_demux(frame, frame_size, sps)) != ERROR_SUCCESS) { if ((ret = avc->sps_demux(frame, frame_size, sps)) != ERROR_SUCCESS) {
return ret; return ret;
} }
if (h264_sps == sps) { if (h264_sps == sps) {
continue; continue;
} }
h264_sps_changed = true; h264_sps_changed = true;
h264_sps = sps; h264_sps = sps;
if ((ret = write_h264_sps_pps(dts, pts)) != ERROR_SUCCESS) { if ((ret = write_h264_sps_pps(dts, pts)) != ERROR_SUCCESS) {
return ret; return ret;
} }
continue; continue;
} }
// for pps // for pps
if (avc->is_pps(frame, frame_size)) { if (avc->is_pps(frame, frame_size)) {
std::string pps; std::string pps;
if ((ret = avc->pps_demux(frame, frame_size, pps)) != ERROR_SUCCESS) { if ((ret = avc->pps_demux(frame, frame_size, pps)) != ERROR_SUCCESS) {
return ret; return ret;
} }
if (h264_pps == pps) { if (h264_pps == pps) {
continue; continue;
} }
h264_pps_changed = true; h264_pps_changed = true;
h264_pps = pps; h264_pps = pps;
if ((ret = write_h264_sps_pps(dts, pts)) != ERROR_SUCCESS) { if ((ret = write_h264_sps_pps(dts, pts)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -456,11 +456,11 @@ int SrsMpegtsOverUdp::write_h264_sps_pps(uint32_t dts, uint32_t pts)
h264_sps_changed = false; h264_sps_changed = false;
h264_pps_changed = false; h264_pps_changed = false;
h264_sps_pps_sent = true; h264_sps_pps_sent = true;
return ret; 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; 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) { if (nal_unit_type == SrsAvcNaluTypeIDR) {
frame_type = SrsVideoAvcFrameTypeKeyFrame; frame_type = SrsVideoAvcFrameTypeKeyFrame;
} }
std::string ibp; std::string ibp;
if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) { if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) {
return ret; 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 SrsMpegtsOverUdp::on_ts_audio(SrsTsMessage* msg, SrsBuffer* avs)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// ensure rtmp connected. // ensure rtmp connected.
if ((ret = connect()) != ERROR_SUCCESS) { if ((ret = connect()) != ERROR_SUCCESS) {
return ret; return ret;
} }
// ts tbn to flv tbn. // ts tbn to flv tbn.
uint32_t dts = (uint32_t)(msg->dts / 90); 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) { if ((ret = aac->adts_demux(avs, &frame, &frame_size, codec)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// ignore invalid frame, // ignore invalid frame,
// * atleast 1bytes for aac to decode the data. // * atleast 1bytes for aac to decode the data.
if (frame_size <= 0) { if (frame_size <= 0) {
continue; continue;
} }
srs_info("mpegts: demux aac frame size=%d, dts=%d", frame_size, dts); srs_info("mpegts: demux aac frame size=%d, dts=%d", frame_size, dts);
// generate sh. // generate sh.
if (aac_specific_config.empty()) { if (aac_specific_config.empty()) {
std::string sh; std::string sh;
@ -533,28 +533,28 @@ int SrsMpegtsOverUdp::on_ts_audio(SrsTsMessage* msg, SrsBuffer* avs)
return ret; return ret;
} }
aac_specific_config = sh; aac_specific_config = sh;
codec.aac_packet_type = 0; codec.aac_packet_type = 0;
if ((ret = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), &codec, dts)) != ERROR_SUCCESS) { if ((ret = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), &codec, dts)) != ERROR_SUCCESS) {
return ret; return ret;
} }
} }
// audio raw data. // audio raw data.
codec.aac_packet_type = 1; codec.aac_packet_type = 1;
if ((ret = write_audio_raw_frame(frame, frame_size, &codec, dts)) != ERROR_SUCCESS) { if ((ret = write_audio_raw_frame(frame, frame_size, &codec, dts)) != ERROR_SUCCESS) {
return ret; return ret;
} }
} }
return ret; return ret;
} }
int SrsMpegtsOverUdp::write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts) int SrsMpegtsOverUdp::write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
char* data = NULL; char* data = NULL;
int size = 0; int size = 0;
if ((ret = aac->mux_aac2flv(frame, frame_size, codec, dts, &data, &size)) != ERROR_SUCCESS) { 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; return ret;
} }
srs_assert(msg); srs_assert(msg);
// push msg to queue. // push msg to queue.
if ((ret = queue->push(msg)) != ERROR_SUCCESS) { if ((ret = queue->push(msg)) != ERROR_SUCCESS) {
srs_error("mpegts: push msg to queue failed. ret=%d", ret); srs_error("mpegts: push msg to queue failed. ret=%d", ret);
return ret; return ret;
} }
// for all ready msg, dequeue and send out. // for all ready msg, dequeue and send out.
for (;;) { for (;;) {
if ((msg = queue->dequeue()) == NULL) { if ((msg = queue->dequeue()) == NULL) {
break; break;
} }
if (pprint->can_print()) { if (pprint->can_print()) {
srs_trace("mpegts: send msg %s age=%d, dts=%"PRId64", size=%d", 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. // send out encoded msg.
if ((ret = sdk->send_and_free_message(msg)) != ERROR_SUCCESS) { if ((ret = sdk->send_and_free_message(msg)) != ERROR_SUCCESS) {
close(); close();
@ -610,7 +610,7 @@ int SrsMpegtsOverUdp::rtmp_write_packet(char type, uint32_t timestamp, char* dat
int SrsMpegtsOverUdp::connect() int SrsMpegtsOverUdp::connect()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// Ignore when connected. // Ignore when connected.
if (sdk) { if (sdk) {
return ret; return ret;
@ -631,7 +631,7 @@ int SrsMpegtsOverUdp::connect()
srs_error("mpegts: publish failed. ret=%d", ret); srs_error("mpegts: publish failed. ret=%d", ret);
return ret; return ret;
} }
return ret; return ret;
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_MPEGTS_UDP_HPP #ifndef SRS_APP_MPEGTS_UDP_HPP
#define SRS_APP_MPEGTS_UDP_HPP #define SRS_APP_MPEGTS_UDP_HPP
/*
#include <srs_app_mpegts_udp.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#ifdef SRS_AUTO_STREAM_CASTER #ifdef SRS_AUTO_STREAM_CASTER
@ -55,10 +51,10 @@ class SrsSimpleRtmpClient;
#include <srs_app_listener.hpp> #include <srs_app_listener.hpp>
/** /**
* the queue for mpegts over udp to send packets. * the queue for mpegts over udp to send packets.
* for the aac in mpegts contains many flv packets in a pes packet, * for the aac in mpegts contains many flv packets in a pes packet,
* we must recalc the timestamp. * we must recalc the timestamp.
*/ */
class SrsMpegtsQueue class SrsMpegtsQueue
{ {
private: private:
@ -75,10 +71,10 @@ public:
}; };
/** /**
* the mpegts over udp stream caster. * the mpegts over udp stream caster.
*/ */
class SrsMpegtsOverUdp : virtual public ISrsTsHandler class SrsMpegtsOverUdp : virtual public ISrsTsHandler
, virtual public ISrsUdpHandler , virtual public ISrsUdpHandler
{ {
private: private:
SrsBuffer* stream; SrsBuffer* stream;

View file

@ -1,24 +1,24 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_ng_exec.hpp> #include <srs_app_ng_exec.hpp>

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_NG_EXEC_HPP #ifndef SRS_APP_NG_EXEC_HPP
#define SRS_APP_NG_EXEC_HPP #define SRS_APP_NG_EXEC_HPP
/*
#include <srs_app_ng_exec.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <vector> #include <vector>

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_pithy_print.hpp> #include <srs_app_pithy_print.hpp>
@ -74,7 +74,7 @@ int SrsStageInfo::on_reload_pithy_print()
update_print_time(); update_print_time();
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static std::map<int, SrsStageInfo*> _srs_stages; static std::map<int, SrsStageInfo*> _srs_stages;
SrsPithyPrint::SrsPithyPrint(int _stage_id) SrsPithyPrint::SrsPithyPrint(int _stage_id)
@ -185,9 +185,9 @@ int SrsPithyPrint::enter_stage()
srs_assert(stage != NULL); srs_assert(stage != NULL);
client_id = stage->nb_clients++; client_id = stage->nb_clients++;
srs_verbose("enter stage, stage_id=%d, client_id=%d, nb_clients=%d, time_ms=%d", 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; return client_id;
} }
@ -198,9 +198,9 @@ void SrsPithyPrint::leave_stage()
srs_assert(stage != NULL); srs_assert(stage != NULL);
stage->nb_clients--; stage->nb_clients--;
srs_verbose("leave stage, stage_id=%d, client_id=%d, nb_clients=%d, time_ms=%d", 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() void SrsPithyPrint::elapse()

View file

@ -1,40 +1,36 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_PITHY_PRINT_HPP #ifndef SRS_APP_PITHY_PRINT_HPP
#define SRS_APP_PITHY_PRINT_HPP #define SRS_APP_PITHY_PRINT_HPP
/*
#include <srs_app_pithy_print.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <srs_app_reload.hpp> #include <srs_app_reload.hpp>
/** /**
* the stage info to calc the age. * the stage info to calc the age.
*/ */
class SrsStageInfo : public ISrsReloadHandler class SrsStageInfo : public ISrsReloadHandler
{ {
public: public:
@ -63,16 +59,16 @@ public:
* if there is 1client, it will print every 3s. * if there is 1client, it will print every 3s.
* if there is 10clients, random select one to print every 3s. * if there is 10clients, random select one to print every 3s.
* Usage: * Usage:
SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_play(); * SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_play();
SrsAutoFree(SrsPithyPrint, pprint); * SrsAutoFree(SrsPithyPrint, pprint);
while (true) { * while (true) {
pprint->elapse(); * pprint->elapse();
if (pprint->can_print()) { * if (pprint->can_print()) {
// print pithy message. * // print pithy message.
// user can get the elapse time by: pprint->age() * // user can get the elapse time by: pprint->age()
} * }
// read and write RTMP messages. * // read and write RTMP messages.
} * }
*/ */
class SrsPithyPrint class SrsPithyPrint
{ {
@ -99,25 +95,25 @@ public:
virtual ~SrsPithyPrint(); virtual ~SrsPithyPrint();
private: private:
/** /**
* enter the specified stage, return the client id. * enter the specified stage, return the client id.
*/ */
virtual int enter_stage(); virtual int enter_stage();
/** /**
* leave the specified stage, release the client id. * leave the specified stage, release the client id.
*/ */
virtual void leave_stage(); virtual void leave_stage();
public: public:
/** /**
* auto calc the elapse time * auto calc the elapse time
*/ */
virtual void elapse(); virtual void elapse();
/** /**
* whether current client can print. * whether current client can print.
*/ */
virtual bool can_print(); virtual bool can_print();
/** /**
* get the elapsed time in ms. * get the elapsed time in ms.
*/ */
virtual int64_t age(); virtual int64_t age();
}; };

View file

@ -1,24 +1,24 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_process.hpp> #include <srs_app_process.hpp>
@ -253,7 +253,7 @@ int SrsProcess::start()
if (pid > 0) { if (pid > 0) {
is_started = true; is_started = true;
srs_trace("fored process, pid=%d, bin=%s, stdout=%s, stderr=%s, argv=%s", 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; return ret;
} }

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_PROCESS_HPP #ifndef SRS_APP_PROCESS_HPP
#define SRS_APP_PROCESS_HPP #define SRS_APP_PROCESS_HPP
/*
#include <srs_app_process.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_recv_thread.hpp> #include <srs_app_recv_thread.hpp>
@ -65,7 +65,7 @@ SrsRecvThread::~SrsRecvThread()
{ {
// stop recv thread. // stop recv thread.
stop(); stop();
// destroy the thread. // destroy the thread.
srs_freep(trd); srs_freep(trd);
} }
@ -93,37 +93,37 @@ void SrsRecvThread::stop_loop()
int SrsRecvThread::cycle() int SrsRecvThread::cycle()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
while (!trd->interrupted()) { while (!trd->interrupted()) {
// When the pumper is interrupted, wait then retry. // When the pumper is interrupted, wait then retry.
if (pumper->interrupted()) { if (pumper->interrupted()) {
st_usleep(timeout * 1000); st_usleep(timeout * 1000);
continue; continue;
} }
SrsCommonMessage* msg = NULL; SrsCommonMessage* msg = NULL;
// Process the received message. // Process the received message.
if ((ret = rtmp->recv_message(&msg)) == ERROR_SUCCESS) { if ((ret = rtmp->recv_message(&msg)) == ERROR_SUCCESS) {
ret = pumper->consume(msg); ret = pumper->consume(msg);
} }
if (ret != ERROR_SUCCESS) { if (ret != ERROR_SUCCESS) {
if (!srs_is_client_gracefully_close(ret) && !srs_is_system_control_error(ret)) { if (!srs_is_client_gracefully_close(ret) && !srs_is_system_control_error(ret)) {
srs_error("recv thread error. ret=%d", ret); srs_error("recv thread error. ret=%d", ret);
} }
// Interrupt the receive thread for any error. // Interrupt the receive thread for any error.
trd->interrupt(); trd->interrupt();
// Notify the pumper to quit for error. // Notify the pumper to quit for error.
pumper->interrupt(ret); pumper->interrupt(ret);
return ret; return ret;
} }
srs_verbose("thread loop recv message. ret=%d", ret); srs_verbose("thread loop recv message. ret=%d", ret);
} }
return ret; return ret;
} }
@ -148,7 +148,7 @@ void SrsRecvThread::on_thread_stop()
} }
SrsQueueRecvThread::SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, int timeout_ms) SrsQueueRecvThread::SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, int timeout_ms)
: trd(this, rtmp_sdk, timeout_ms) : trd(this, rtmp_sdk, timeout_ms)
{ {
_consumer = consumer; _consumer = consumer;
rtmp = rtmp_sdk; rtmp = rtmp_sdk;
@ -158,7 +158,7 @@ SrsQueueRecvThread::SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtm
SrsQueueRecvThread::~SrsQueueRecvThread() SrsQueueRecvThread::~SrsQueueRecvThread()
{ {
stop(); stop();
// clear all messages. // clear all messages.
std::vector<SrsCommonMessage*>::iterator it; std::vector<SrsCommonMessage*>::iterator it;
for (it = queue.begin(); it != queue.end(); ++it) { for (it = queue.begin(); it != queue.end(); ++it) {
@ -251,17 +251,14 @@ void SrsQueueRecvThread::on_stop()
rtmp->set_auto_response(true); rtmp->set_auto_response(true);
} }
SrsPublishRecvThread::SrsPublishRecvThread( SrsPublishRecvThread::SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest* _req, int mr_sock_fd, int timeout_ms, SrsRtmpConn* conn, SrsSource* source)
SrsRtmpServer* rtmp_sdk, : trd(this, rtmp_sdk, timeout_ms)
SrsRequest* _req, int mr_sock_fd, int timeout_ms,
SrsRtmpConn* conn, SrsSource* source
): trd(this, rtmp_sdk, timeout_ms)
{ {
rtmp = rtmp_sdk; rtmp = rtmp_sdk;
_conn = conn; _conn = conn;
_source = source; _source = source;
recv_error_code = ERROR_SUCCESS; recv_error_code = ERROR_SUCCESS;
_nb_msgs = 0; _nb_msgs = 0;
error = st_cond_new(); error = st_cond_new();
@ -269,8 +266,8 @@ SrsPublishRecvThread::SrsPublishRecvThread(
req = _req; req = _req;
mr_fd = mr_sock_fd; mr_fd = mr_sock_fd;
// the mr settings, // the mr settings,
// @see https://github.com/ossrs/srs/issues/241 // @see https://github.com/ossrs/srs/issues/241
mr = _srs_config->get_mr_enabled(req->vhost); mr = _srs_config->get_mr_enabled(req->vhost);
mr_sleep = _srs_config->get_mr_sleep_ms(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, // we donot set the auto response to false,
// for the main thread never send message. // for the main thread never send message.
#ifdef SRS_PERF_MERGED_READ #ifdef SRS_PERF_MERGED_READ
if (mr) { if (mr) {
// set underlayer buffer size // set underlayer buffer size
set_socket_buffer(mr_sleep); set_socket_buffer(mr_sleep);
// disable the merge read // disable the merge read
// @see https://github.com/ossrs/srs/issues/241 // @see https://github.com/ossrs/srs/issues/241
rtmp->set_merge_read(true, this); rtmp->set_merge_read(true, this);
@ -398,7 +395,7 @@ void SrsPublishRecvThread::on_stop()
// when thread stop, signal the conn thread which wait. // when thread stop, signal the conn thread which wait.
// @see https://github.com/ossrs/srs/issues/244 // @see https://github.com/ossrs/srs/issues/244
st_cond_signal(error); st_cond_signal(error);
#ifdef SRS_PERF_MERGED_READ #ifdef SRS_PERF_MERGED_READ
if (mr) { if (mr) {
// disable the merge read // disable the merge read
@ -420,11 +417,11 @@ void SrsPublishRecvThread::on_read(ssize_t nread)
} }
/** /**
* to improve read performance, merge some packets then read, * to improve read performance, merge some packets then read,
* when it on and read small bytes, we sleep to wait more data., * when it on and read small bytes, we sleep to wait more data.,
* that is, we merge some data to read together. * that is, we merge some data to read together.
* @see https://github.com/ossrs/srs/issues/241 * @see https://github.com/ossrs/srs/issues/241
*/ */
if (nread < SRS_MR_SMALL_BYTES) { if (nread < SRS_MR_SMALL_BYTES) {
st_usleep(mr_sleep * 1000); st_usleep(mr_sleep * 1000);
} }
@ -438,17 +435,17 @@ int SrsPublishRecvThread::on_reload_vhost_publish(string vhost)
if (req->vhost != vhost) { if (req->vhost != vhost) {
return ret; return ret;
} }
// the mr settings, // the mr settings,
// @see https://github.com/ossrs/srs/issues/241 // @see https://github.com/ossrs/srs/issues/241
bool mr_enabled = _srs_config->get_mr_enabled(req->vhost); bool mr_enabled = _srs_config->get_mr_enabled(req->vhost);
int sleep_ms = _srs_config->get_mr_sleep_ms(req->vhost); int sleep_ms = _srs_config->get_mr_sleep_ms(req->vhost);
// update buffer when sleep ms changed. // update buffer when sleep ms changed.
if (mr_sleep != sleep_ms) { if (mr_sleep != sleep_ms) {
set_socket_buffer(sleep_ms); set_socket_buffer(sleep_ms);
} }
#ifdef SRS_PERF_MERGED_READ #ifdef SRS_PERF_MERGED_READ
// mr enabled=>disabled // mr enabled=>disabled
if (mr && !mr_enabled) { if (mr && !mr_enabled) {
@ -463,7 +460,7 @@ int SrsPublishRecvThread::on_reload_vhost_publish(string vhost)
rtmp->set_merge_read(true, this); rtmp->set_merge_read(true, this);
} }
#endif #endif
// update to new state // update to new state
mr = mr_enabled; mr = mr_enabled;
mr_sleep = sleep_ms; mr_sleep = sleep_ms;
@ -505,18 +502,18 @@ void SrsPublishRecvThread::set_socket_buffer(int sleep_ms)
int onb_rbuf = 0; int onb_rbuf = 0;
socklen_t sock_buf_size = sizeof(int); socklen_t sock_buf_size = sizeof(int);
getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &onb_rbuf, &sock_buf_size); getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &onb_rbuf, &sock_buf_size);
// socket recv buffer, system will double it. // socket recv buffer, system will double it.
int nb_rbuf = socket_buffer_size / 2; int nb_rbuf = socket_buffer_size / 2;
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &nb_rbuf, sock_buf_size) < 0) { if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &nb_rbuf, sock_buf_size) < 0) {
srs_warn("set sock SO_RCVBUF=%d failed.", nb_rbuf); srs_warn("set sock SO_RCVBUF=%d failed.", nb_rbuf);
} }
getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &nb_rbuf, &sock_buf_size); 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", 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, mr_sleep, sleep_ms, socket_buffer_size, onb_rbuf, nb_rbuf,
SRS_MR_SMALL_BYTES, realtime); SRS_MR_SMALL_BYTES, realtime);
rtmp->set_recv_buffer(nb_rbuf); rtmp->set_recv_buffer(nb_rbuf);
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_RECV_THREAD_HPP #ifndef SRS_APP_RECV_THREAD_HPP
#define SRS_APP_RECV_THREAD_HPP #define SRS_APP_RECV_THREAD_HPP
/*
#include <srs_app_recv_thread.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <vector> #include <vector>
@ -119,11 +115,11 @@ public:
}; };
/** /**
* the recv thread used to replace the timeout recv, * the recv thread used to replace the timeout recv,
* which hurt performance for the epoll_ctrl is frequently used. * which hurt performance for the epoll_ctrl is frequently used.
* @see: SrsRtmpConn::playing * @see: SrsRtmpConn::playing
* @see: https://github.com/ossrs/srs/issues/217 * @see: https://github.com/ossrs/srs/issues/217
*/ */
class SrsQueueRecvThread : public ISrsMessagePumper class SrsQueueRecvThread : public ISrsMessagePumper
{ {
private: private:
@ -154,12 +150,12 @@ public:
}; };
/** /**
* the publish recv thread got message and callback the source method to process message. * the publish recv thread got message and callback the source method to process message.
* @see: https://github.com/ossrs/srs/issues/237 * @see: https://github.com/ossrs/srs/issues/237
*/ */
class SrsPublishRecvThread : virtual public ISrsMessagePumper, virtual public ISrsReloadHandler class SrsPublishRecvThread : virtual public ISrsMessagePumper, virtual public ISrsReloadHandler
#ifdef SRS_PERF_MERGED_READ #ifdef SRS_PERF_MERGED_READ
, virtual public IMergeReadHandler , virtual public IMergeReadHandler
#endif #endif
{ {
private: private:
@ -188,14 +184,12 @@ private:
int cid; int cid;
int ncid; int ncid;
public: public:
SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest* _req, int mr_sock_fd, int timeout_ms, SrsRtmpConn* conn, SrsSource* source);
SrsRequest* _req, int mr_sock_fd, int timeout_ms,
SrsRtmpConn* conn, SrsSource* source);
virtual ~SrsPublishRecvThread(); virtual ~SrsPublishRecvThread();
public: public:
/** /**
* wait for error for some timeout. * wait for error for some timeout.
*/ */
virtual int wait(uint64_t timeout_ms); virtual int wait(uint64_t timeout_ms);
virtual int64_t nb_msgs(); virtual int64_t nb_msgs();
virtual int error_code(); virtual int error_code();

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_refer.hpp> #include <srs_app_refer.hpp>
@ -47,7 +47,7 @@ int SrsRefer::check(std::string page_url, SrsConfDirective* refer)
for (int i = 0; i < (int)refer->args.size(); i++) { for (int i = 0; i < (int)refer->args.size(); i++) {
if ((ret = check_single_refer(page_url, refer->args.at(i))) == ERROR_SUCCESS) { if ((ret = check_single_refer(page_url, refer->args.at(i))) == ERROR_SUCCESS) {
srs_verbose("check refer success. page_url=%s, refer=%s", 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; return ret;
} }
} }
@ -88,7 +88,7 @@ int SrsRefer::check_single_refer(std::string page_url, std::string refer)
if (ret != ERROR_SUCCESS) { if (ret != ERROR_SUCCESS) {
srs_verbose("access denied, page_url=%s, domain_name=%s, refer=%s, ret=%d", 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; return ret;

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_REFER_HPP #ifndef SRS_APP_REFER_HPP
#define SRS_APP_REFER_HPP #define SRS_APP_REFER_HPP
/*
#include <srs_app_refer.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
@ -40,10 +37,10 @@ public:
virtual ~SrsRefer(); virtual ~SrsRefer();
public: public:
/** /**
* to check the refer. * to check the refer.
* @param page_url the client page url. * @param page_url the client page url.
* @param refer the refer in config. * @param refer the refer in config.
*/ */
virtual int check(std::string page_url, SrsConfDirective* refer); virtual int check(std::string page_url, SrsConfDirective* refer);
private: private:
virtual int check_single_refer(std::string page_url, std::string refer); virtual int check_single_refer(std::string page_url, std::string refer);

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_reload.hpp> #include <srs_app_reload.hpp>

View file

@ -1,43 +1,40 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_RELOAD_HPP #ifndef SRS_APP_RELOAD_HPP
#define SRS_APP_RELOAD_HPP #define SRS_APP_RELOAD_HPP
/*
#include <srs_app_reload.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
/** /**
* the handler for config reload. * the handler for config reload.
* when reload callback, the config is updated yet. * when reload callback, the config is updated yet.
* *
* features not support reload, * features not support reload,
* @see: https://github.com/ossrs/srs/wiki/v1_CN_Reload#notsupportedfeatures * @see: https://github.com/ossrs/srs/wiki/v1_CN_Reload#notsupportedfeatures
*/ */
class ISrsReloadHandler class ISrsReloadHandler
{ {
public: public:

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_rtmp_conn.hpp> #include <srs_app_rtmp_conn.hpp>
@ -298,7 +298,7 @@ SrsClientInfo::~SrsClientInfo()
} }
SrsRtmpConn::SrsRtmpConn(SrsServer* svr, st_netfd_t c, string cip) SrsRtmpConn::SrsRtmpConn(SrsServer* svr, st_netfd_t c, string cip)
: SrsConnection(svr, c, cip) : SrsConnection(svr, c, cip)
{ {
server = svr; server = svr;
@ -310,7 +310,7 @@ SrsRtmpConn::SrsRtmpConn(SrsServer* svr, st_netfd_t c, string cip)
kbps = new SrsKbps(); kbps = new SrsKbps();
kbps->set_io(skt, skt); kbps->set_io(skt, skt);
wakable = NULL; wakable = NULL;
mw_sleep = SRS_PERF_MW_SLEEP; mw_sleep = SRS_PERF_MW_SLEEP;
mw_enabled = false; mw_enabled = false;
realtime = SRS_PERF_MIN_LATENCY_ENABLED; realtime = SRS_PERF_MIN_LATENCY_ENABLED;
@ -357,7 +357,7 @@ int SrsRtmpConn::do_cycle()
return ret; return ret;
} }
#endif #endif
rtmp->set_recv_timeout(SRS_CONSTS_RTMP_TMMS); rtmp->set_recv_timeout(SRS_CONSTS_RTMP_TMMS);
rtmp->set_send_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", 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()) { if (req->schema.empty() || req->vhost.empty() || req->port == 0 || req->app.empty()) {
ret = ERROR_RTMP_REQ_TCURL; ret = ERROR_RTMP_REQ_TCURL;
srs_error("discovery tcUrl failed. " srs_error("discovery tcUrl failed. "
"tcUrl=%s, schema=%s, vhost=%s, port=%d, app=%s, ret=%d", "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); req->tcUrl.c_str(), req->schema.c_str(), req->vhost.c_str(), req->port, req->app.c_str(), ret);
return ret; return ret;
} }
@ -402,10 +402,10 @@ int SrsRtmpConn::do_cycle()
srs_verbose("check vhost success."); srs_verbose("check vhost success.");
srs_trace("connect app, " srs_trace("connect app, "
"tcUrl=%s, pageUrl=%s, swfUrl=%s, schema=%s, vhost=%s, port=%d, app=%s, args=%s", "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->tcUrl.c_str(), req->pageUrl.c_str(), req->swfUrl.c_str(),
req->schema.c_str(), req->vhost.c_str(), req->port, req->schema.c_str(), req->vhost.c_str(), req->port,
req->app.c_str(), (req->args? "(obj)":"null")); req->app.c_str(), (req->args? "(obj)":"null"));
// show client identity // show client identity
if(req->args) { if(req->args) {
@ -428,21 +428,21 @@ int SrsRtmpConn::do_cycle()
srs_id = (int)prop->to_number(); srs_id = (int)prop->to_number();
} }
srs_info("edge-srs ip=%s, version=%s, pid=%d, id=%d", 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_server_ip.c_str(), srs_version.c_str(), srs_pid, srs_id);
if (srs_pid > 0) { if (srs_pid > 0) {
srs_trace("edge-srs ip=%s, version=%s, pid=%d, id=%d", 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_server_ip.c_str(), srs_version.c_str(), srs_pid, srs_id);
} }
} }
ret = service_cycle(); ret = service_cycle();
int disc_ret = ERROR_SUCCESS; int disc_ret = ERROR_SUCCESS;
if ((disc_ret = on_disconnect()) != 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); srs_warn("connection on disconnect peer failed, but ignore this error. disc_ret=%d, ret=%d", disc_ret, ret);
} }
return ret; return ret;
} }
@ -457,8 +457,8 @@ int SrsRtmpConn::on_reload_vhost_removed(string vhost)
} }
// if the vhost connected is removed, disconnect the client. // if the vhost connected is removed, disconnect the client.
srs_trace("vhost %s removed/disabled, close client url=%s", srs_trace("vhost %s removed/disabled, close client url=%s",
vhost.c_str(), req->get_stream_url().c_str()); vhost.c_str(), req->get_stream_url().c_str());
// should never close the fd in another thread, // should never close the fd in another thread,
// one fd should managed by one thread, we should use interrupt instead. // 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; send_min_interval = v;
} }
} }
return ret; return ret;
} }
@ -520,7 +520,7 @@ int SrsRtmpConn::on_reload_vhost_realtime(string vhost)
srs_trace("realtime changed %d=>%d", realtime, realtime_enabled); srs_trace("realtime changed %d=>%d", realtime, realtime_enabled);
realtime = realtime_enabled; realtime = realtime_enabled;
} }
return ret; return ret;
} }
@ -568,9 +568,9 @@ void SrsRtmpConn::cleanup()
{ {
kbps->cleanup(); kbps->cleanup();
} }
int SrsRtmpConn::service_cycle() int SrsRtmpConn::service_cycle()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsRequest* req = info->req; SrsRequest* req = info->req;
@ -586,13 +586,13 @@ int SrsRtmpConn::service_cycle()
srs_error("set input window acknowledgement size failed. ret=%d", ret); srs_error("set input window acknowledgement size failed. ret=%d", ret);
return ret; return ret;
} }
if ((ret = rtmp->set_peer_bandwidth((int)(2.5 * 1000 * 1000), 2)) != ERROR_SUCCESS) { if ((ret = rtmp->set_peer_bandwidth((int)(2.5 * 1000 * 1000), 2)) != ERROR_SUCCESS) {
srs_error("set peer bandwidth failed. ret=%d", ret); srs_error("set peer bandwidth failed. ret=%d", ret);
return ret; return ret;
} }
srs_verbose("set peer bandwidth success"); srs_verbose("set peer bandwidth success");
// get the ip which client connected. // get the ip which client connected.
std::string local_ip = srs_get_local_ip(st_netfd_fileno(stfd)); std::string local_ip = srs_get_local_ip(st_netfd_fileno(stfd));
@ -630,7 +630,7 @@ int SrsRtmpConn::service_cycle()
return ret; return ret;
} }
srs_verbose("response connect app success"); srs_verbose("response connect app success");
if ((ret = rtmp->on_bw_done()) != ERROR_SUCCESS) { if ((ret = rtmp->on_bw_done()) != ERROR_SUCCESS) {
srs_error("on_bw_done failed. ret=%d", ret); srs_error("on_bw_done failed. ret=%d", ret);
return ret; return ret;
@ -664,7 +664,7 @@ int SrsRtmpConn::service_cycle()
continue; continue;
} }
// for "some" system control error, // for "some" system control error,
// logical accept and retry stream service. // logical accept and retry stream service.
if (ret == ERROR_CONTROL_RTMP_CLOSE) { if (ret == ERROR_CONTROL_RTMP_CLOSE) {
// TODO: FIXME: use ping message to anti-death of socket. // TODO: FIXME: use ping message to anti-death of socket.
@ -698,8 +698,8 @@ int SrsRtmpConn::stream_service_cycle()
return ret; return ret;
} }
req->strip(); req->strip();
srs_trace("client identified, type=%s, stream_name=%s, duration=%.2f", 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_client_type_string(info->type).c_str(), req->stream.c_str(), req->duration);
// security check // security check
if ((ret = security->check(info->type, ip, req)) != ERROR_SUCCESS) { if ((ret = security->check(info->type, ip, req)) != ERROR_SUCCESS) {
@ -707,7 +707,7 @@ int SrsRtmpConn::stream_service_cycle()
return ret; return ret;
} }
srs_info("security check ok"); srs_info("security check ok");
// client is identified, set the timeout to service timeout. // client is identified, set the timeout to service timeout.
rtmp->set_recv_timeout(SRS_CONSTS_RTMP_TMMS); rtmp->set_recv_timeout(SRS_CONSTS_RTMP_TMMS);
rtmp->set_send_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); srs_error("stat client failed. ret=%d", ret);
return ret; return ret;
} }
bool enabled_cache = _srs_config->get_gop_cache(req->vhost); 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]", 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, req->get_stream_url().c_str(), ip.c_str(), enabled_cache, info->edge,
source->source_id(), source->source_id()); source->source_id(), source->source_id());
source->set_cache(enabled_cache); source->set_cache(enabled_cache);
switch (info->type) { switch (info->type) {
@ -778,7 +778,7 @@ int SrsRtmpConn::stream_service_cycle()
return ret; return ret;
} }
} }
return ret; return ret;
} }
@ -834,8 +834,8 @@ int SrsRtmpConn::playing(SrsSource* source)
} }
SrsAutoFree(SrsConsumer, consumer); SrsAutoFree(SrsConsumer, consumer);
srs_verbose("consumer created success."); srs_verbose("consumer created success.");
// use isolate thread to recv, // use isolate thread to recv,
// @see: https://github.com/ossrs/srs/issues/217 // @see: https://github.com/ossrs/srs/issues/217
SrsQueueRecvThread trd(consumer, rtmp, SRS_PERF_MW_SLEEP); SrsQueueRecvThread trd(consumer, rtmp, SRS_PERF_MW_SLEEP);
@ -879,7 +879,7 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe
// initialize other components // initialize other components
SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_play(); SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_play();
SrsAutoFree(SrsPithyPrint, pprint); SrsAutoFree(SrsPithyPrint, pprint);
SrsMessageArray msgs(SRS_PERF_MW_MSGS); SrsMessageArray msgs(SRS_PERF_MW_MSGS);
bool user_specified_duration_to_stop = (req->duration > 0); bool user_specified_duration_to_stop = (req->duration > 0);
int64_t starttime = -1; int64_t starttime = -1;
@ -897,7 +897,7 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe
set_sock_options(); set_sock_options();
srs_trace("start play smi=%.2f, mw_sleep=%d, mw_enabled=%d, realtime=%d, tcp_nodelay=%d", 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) { while (!disposed) {
// collect elapse for pithy print. // 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); srs_error("connection expired. ret=%d", ret);
return ret; return ret;
} }
// to use isolate thread to recv, can improve about 33% performance. // 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/196
// @see: https://github.com/ossrs/srs/issues/217 // @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); srs_error("get messages from consumer failed. ret=%d", ret);
return ret; return ret;
} }
// reportable // reportable
if (pprint->can_print()) { if (pprint->can_print()) {
kbps->sample(); kbps->sample();
srs_trace("-> "SRS_CONSTS_LOG_PLAY srs_trace("-> "SRS_CONSTS_LOG_PLAY
" time=%"PRId64", msgs=%d, okbps=%d,%d,%d, ikbps=%d,%d,%d, mw=%d", " time=%"PRId64", msgs=%d, okbps=%d,%d,%d, ikbps=%d,%d,%d, mw=%d",
pprint->age(), count, pprint->age(), count,
kbps->get_send_kbps(), kbps->get_send_kbps_30s(), kbps->get_send_kbps_5m(), 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(), kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m(),
mw_sleep mw_sleep
); );
} }
// we use wait timeout to get messages, // we use wait timeout to get messages,
// for min latency event no message incoming, // for min latency event no message incoming,
// so the count maybe zero. // so the count maybe zero.
if (count > 0) { if (count > 0) {
srs_verbose("mw wait %dms and got %d msgs %d(%"PRId64"-%"PRId64")ms", srs_verbose("mw wait %dms and got %d msgs %d(%"PRId64"-%"PRId64")ms",
mw_sleep, count, mw_sleep, count,
(count > 0? msgs.msgs[count - 1]->timestamp - msgs.msgs[0]->timestamp : 0), (count > 0? msgs.msgs[count - 1]->timestamp - msgs.msgs[0]->timestamp : 0),
(count > 0? msgs.msgs[0]->timestamp : 0), (count > 0? msgs.msgs[0]->timestamp : 0),
(count > 0? msgs.msgs[count - 1]->timestamp : 0)); (count > 0? msgs.msgs[count - 1]->timestamp : 0));
} }
if (count <= 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); 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. // we start to collect the durations for each message.
if (user_specified_duration_to_stop) { if (user_specified_duration_to_stop) {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
@ -1053,20 +1053,20 @@ int SrsRtmpConn::publishing(SrsSource* source)
} }
srs_verbose("check publish_refer success."); srs_verbose("check publish_refer success.");
} }
if ((ret = http_hooks_on_publish()) != ERROR_SUCCESS) { if ((ret = http_hooks_on_publish()) != ERROR_SUCCESS) {
srs_error("http hook on_publish failed. ret=%d", ret); srs_error("http hook on_publish failed. ret=%d", ret);
return ret; return ret;
} }
if ((ret = acquire_publish(source)) == ERROR_SUCCESS) { if ((ret = acquire_publish(source)) == ERROR_SUCCESS) {
// use isolate thread to recv, // use isolate thread to recv,
// @see: https://github.com/ossrs/srs/issues/237 // @see: https://github.com/ossrs/srs/issues/237
SrsPublishRecvThread trd(rtmp, req, st_netfd_fileno(stfd), 0, this, source); SrsPublishRecvThread trd(rtmp, req, st_netfd_fileno(stfd), 0, this, source);
srs_info("start to publish stream %s success", req->stream.c_str()); srs_info("start to publish stream %s success", req->stream.c_str());
ret = do_publishing(source, &trd); ret = do_publishing(source, &trd);
// stop isolate recv thread // stop isolate recv thread
trd.stop(); trd.stop();
} }
@ -1079,9 +1079,9 @@ int SrsRtmpConn::publishing(SrsSource* source)
if (ret != ERROR_SYSTEM_STREAM_BUSY) { if (ret != ERROR_SYSTEM_STREAM_BUSY) {
release_publish(source); release_publish(source);
} }
http_hooks_on_unpublish(); http_hooks_on_unpublish();
return ret; return ret;
} }
@ -1092,7 +1092,7 @@ int SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* trd)
SrsRequest* req = info->req; SrsRequest* req = info->req;
SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_publish(); SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_publish();
SrsAutoFree(SrsPithyPrint, pprint); SrsAutoFree(SrsPithyPrint, pprint);
// start isolate recv thread. // start isolate recv thread.
if ((ret = trd->start()) != ERROR_SUCCESS) { if ((ret = trd->start()) != ERROR_SUCCESS) {
srs_error("start isolate recv thread failed. ret=%d", ret); 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", 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); mr, mr_sleep, publish_1stpkt_timeout, publish_normal_timeout, tcp_nodelay, receive_thread_cid);
} }
int64_t nb_msgs = 0; int64_t nb_msgs = 0;
while (!disposed) { while (!disposed) {
pprint->elapse(); pprint->elapse();
@ -1128,7 +1128,7 @@ int SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* trd)
srs_error("connection expired. ret=%d", ret); srs_error("connection expired. ret=%d", ret);
return ret; return ret;
} }
// cond wait for timeout. // cond wait for timeout.
if (nb_msgs == 0) { if (nb_msgs == 0) {
// when not got msgs, wait for a larger timeout. // when not got msgs, wait for a larger timeout.
@ -1137,7 +1137,7 @@ int SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* trd)
} else { } else {
trd->wait(publish_normal_timeout); trd->wait(publish_normal_timeout);
} }
// check the thread error code. // check the thread error code.
if ((ret = trd->error_code()) != ERROR_SUCCESS) { if ((ret = trd->error_code()) != ERROR_SUCCESS) {
if (!srs_is_system_control_error(ret) && !srs_is_client_gracefully_close(ret)) { 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; return ret;
} }
// when not got any messages, timeout. // when not got any messages, timeout.
if (trd->nb_msgs() <= nb_msgs) { if (trd->nb_msgs() <= nb_msgs) {
ret = ERROR_SOCKET_TIMEOUT; ret = ERROR_SOCKET_TIMEOUT;
srs_warn("publish timeout %dms, nb_msgs=%"PRId64", ret=%d", 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; break;
} }
nb_msgs = trd->nb_msgs(); nb_msgs = trd->nb_msgs();
// reportable // reportable
if (pprint->can_print()) { if (pprint->can_print()) {
kbps->sample(); kbps->sample();
bool mr = _srs_config->get_mr_enabled(req->vhost); bool mr = _srs_config->get_mr_enabled(req->vhost);
int mr_sleep = _srs_config->get_mr_sleep_ms(req->vhost); int mr_sleep = _srs_config->get_mr_sleep_ms(req->vhost);
srs_trace("<- "SRS_CONSTS_LOG_CLIENT_PUBLISH 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(), " 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_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(), kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m(),
mr, mr_sleep, publish_1stpkt_timeout, publish_normal_timeout mr, mr_sleep, publish_1stpkt_timeout, publish_normal_timeout
); );
} }
} }
return ret; return ret;
} }
@ -1180,8 +1180,8 @@ int SrsRtmpConn::acquire_publish(SrsSource* source)
if (!source->can_publish(info->edge)) { if (!source->can_publish(info->edge)) {
ret = ERROR_SYSTEM_STREAM_BUSY; ret = ERROR_SYSTEM_STREAM_BUSY;
srs_warn("stream %s is already publishing. ret=%d", srs_warn("stream %s is already publishing. ret=%d",
req->get_stream_url().c_str(), ret); req->get_stream_url().c_str(), ret);
return ret; return ret;
} }
@ -1190,17 +1190,17 @@ int SrsRtmpConn::acquire_publish(SrsSource* source)
if ((ret = source->on_edge_start_publish()) != ERROR_SUCCESS) { if ((ret = source->on_edge_start_publish()) != ERROR_SUCCESS) {
srs_error("notice edge start publish stream failed. ret=%d", ret); srs_error("notice edge start publish stream failed. ret=%d", ret);
return ret; return ret;
} }
} else { } else {
if ((ret = source->on_publish()) != ERROR_SUCCESS) { if ((ret = source->on_publish()) != ERROR_SUCCESS) {
srs_error("notify publish failed. ret=%d", ret); srs_error("notify publish failed. ret=%d", ret);
return ret; return ret;
} }
} }
return ret; return ret;
} }
void SrsRtmpConn::release_publish(SrsSource* source) void SrsRtmpConn::release_publish(SrsSource* source)
{ {
// when edge, notice edge to change state. // when edge, notice edge to change state.
@ -1224,7 +1224,7 @@ int SrsRtmpConn::handle_publish_message(SrsSource* source, SrsCommonMessage* msg
return ret; return ret;
} }
SrsAutoFree(SrsPacket, pkt); SrsAutoFree(SrsPacket, pkt);
// for flash, any packet is republish. // for flash, any packet is republish.
if (info->type == SrsRtmpConnFlashPublish) { if (info->type == SrsRtmpConnFlashPublish) {
// flash unpublish. // flash unpublish.
@ -1232,7 +1232,7 @@ int SrsRtmpConn::handle_publish_message(SrsSource* source, SrsCommonMessage* msg
srs_trace("flash flash publish finished."); srs_trace("flash flash publish finished.");
return ERROR_CONTROL_REPUBLISH; return ERROR_CONTROL_REPUBLISH;
} }
// for fmle, drop others except the fmle start packet. // for fmle, drop others except the fmle start packet.
if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) { if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
SrsFMLEStartPacket* unpublish = dynamic_cast<SrsFMLEStartPacket*>(pkt); SrsFMLEStartPacket* unpublish = dynamic_cast<SrsFMLEStartPacket*>(pkt);
@ -1241,11 +1241,11 @@ int SrsRtmpConn::handle_publish_message(SrsSource* source, SrsCommonMessage* msg
} }
return ERROR_CONTROL_REPUBLISH; return ERROR_CONTROL_REPUBLISH;
} }
srs_trace("fmle ignore AMF0/AMF3 command message."); srs_trace("fmle ignore AMF0/AMF3 command message.");
return ret; return ret;
} }
// video, audio, data message // video, audio, data message
if ((ret = process_publish_message(source, msg)) != ERROR_SUCCESS) { if ((ret = process_publish_message(source, msg)) != ERROR_SUCCESS) {
srs_error("fmle process publish message failed. ret=%d", ret); 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; return ret;
} }
SrsAutoFree(SrsPacket, pkt); SrsAutoFree(SrsPacket, pkt);
if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) { if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) {
SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt); SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt);
if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) { 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); srs_error("rtmp process play client pause failed. ret=%d", ret);
return ret; return ret;
} }
if ((ret = consumer->on_play_client_pause(pause->is_pause)) != ERROR_SUCCESS) { if ((ret = consumer->on_play_client_pause(pause->is_pause)) != ERROR_SUCCESS) {
srs_error("consumer process play client pause failed. ret=%d", ret); srs_error("consumer process play client pause failed. ret=%d", ret);
return ret; return ret;
@ -1421,14 +1421,14 @@ void SrsRtmpConn::change_mw_sleep(int sleep_ms)
// 2000*5000/8=1250000B(about 1220KB). // 2000*5000/8=1250000B(about 1220KB).
int kbps = 5000; int kbps = 5000;
int socket_buffer_size = sleep_ms * kbps / 8; int socket_buffer_size = sleep_ms * kbps / 8;
// socket send buffer, system will double it. // socket send buffer, system will double it.
int nb_sbuf = socket_buffer_size / 2; int nb_sbuf = socket_buffer_size / 2;
// override the send buffer by macro. // 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; nb_sbuf = SRS_PERF_SO_SNDBUF_SIZE / 2;
#endif #endif
// set the socket send buffer when required larger buffer // set the socket send buffer when required larger buffer
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &nb_sbuf, sock_buf_size) < 0) { 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); 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", 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, mw_sleep, sleep_ms, SRS_PERF_MW_MSGS, socket_buffer_size,
onb_sbuf, nb_sbuf, realtime); onb_sbuf, nb_sbuf, realtime);
#else #else
srs_trace("mw changed sleep %d=>%d, max_msgs=%d, sbuf %d, realtime=%d", 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); mw_sleep, sleep_ms, SRS_PERF_MW_MSGS, onb_sbuf, realtime);
#endif #endif
mw_sleep = sleep_ms; mw_sleep = sleep_ms;
} }
@ -1456,19 +1456,19 @@ void SrsRtmpConn::set_sock_options()
tcp_nodelay = nvalue; tcp_nodelay = nvalue;
#ifdef SRS_PERF_TCP_NODELAY #ifdef SRS_PERF_TCP_NODELAY
int fd = st_netfd_fileno(stfd); int fd = st_netfd_fileno(stfd);
socklen_t nb_v = sizeof(int); socklen_t nb_v = sizeof(int);
int ov = 0; int ov = 0;
getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &ov, &nb_v); getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &ov, &nb_v);
int v = tcp_nodelay; int v = tcp_nodelay;
// set the socket send buffer when required larger buffer // set the socket send buffer when required larger buffer
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, nb_v) < 0) { if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, nb_v) < 0) {
srs_warn("set sock TCP_NODELAY=%d failed.", v); srs_warn("set sock TCP_NODELAY=%d failed.", v);
} }
getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, &nb_v); getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, &nb_v);
srs_trace("set TCP_NODELAY %d=>%d", ov, v); srs_trace("set TCP_NODELAY %d=>%d", ov, v);
#else #else
srs_warn("SRS_PERF_TCP_NODELAY is disabled but tcp_nodelay configed."); 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; string server;
int port = SRS_CONSTS_RTMP_DEFAULT_PORT; int port = SRS_CONSTS_RTMP_DEFAULT_PORT;
srs_parse_hostport(hostport, server, port); srs_parse_hostport(hostport, server, port);
SrsTcpClient* transport = new SrsTcpClient(server, port, SRS_EDGE_TOKEN_TRAVERSE_TMMS); SrsTcpClient* transport = new SrsTcpClient(server, port, SRS_EDGE_TOKEN_TRAVERSE_TMMS);
SrsAutoFree(SrsTcpClient, transport); SrsAutoFree(SrsTcpClient, transport);
@ -1521,7 +1521,7 @@ int SrsRtmpConn::do_token_traverse_auth(SrsRtmpClient* client)
SrsRequest* req = info->req; SrsRequest* req = info->req;
srs_assert(client); srs_assert(client);
client->set_recv_timeout(SRS_CONSTS_RTMP_TMMS); client->set_recv_timeout(SRS_CONSTS_RTMP_TMMS);
client->set_send_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 SrsRtmpConn::on_disconnect()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
http_hooks_on_close(); http_hooks_on_close();
#ifdef SRS_AUTO_KAFKA #ifdef SRS_AUTO_KAFKA
@ -1553,9 +1553,9 @@ int SrsRtmpConn::on_disconnect()
return ret; return ret;
} }
#endif #endif
// TODO: implements it. // TODO: implements it.
return ret; return ret;
} }
@ -1592,7 +1592,7 @@ int SrsRtmpConn::http_hooks_on_connect()
return ret; return ret;
} }
} }
return ret; return ret;
} }
@ -1659,7 +1659,7 @@ int SrsRtmpConn::http_hooks_on_publish()
return ret; return ret;
} }
} }
return ret; return ret;
} }
@ -1726,7 +1726,7 @@ int SrsRtmpConn::http_hooks_on_play()
return ret; return ret;
} }
} }
return ret; return ret;
} }
@ -1758,7 +1758,7 @@ void SrsRtmpConn::http_hooks_on_stop()
std::string url = hooks.at(i); std::string url = hooks.at(i);
SrsHttpHooks::on_stop(url, req); SrsHttpHooks::on_stop(url, req);
} }
return; return;
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_RTMP_CONN_HPP #ifndef SRS_APP_RTMP_CONN_HPP
#define SRS_APP_RTMP_CONN_HPP #define SRS_APP_RTMP_CONN_HPP
/*
#include <srs_app_rtmp_conn.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_rtsp.hpp> #include <srs_app_rtsp.hpp>
@ -79,22 +79,22 @@ int SrsRtpConn::listen()
int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
pprint->elapse(); pprint->elapse();
if (true) { if (true) {
SrsBuffer stream; SrsBuffer stream;
if ((ret = stream.initialize(buf, nb_buf)) != ERROR_SUCCESS) { if ((ret = stream.initialize(buf, nb_buf)) != ERROR_SUCCESS) {
return ret; return ret;
} }
SrsRtpPacket pkt; SrsRtpPacket pkt;
if ((ret = pkt.decode(&stream)) != ERROR_SUCCESS) { if ((ret = pkt.decode(&stream)) != ERROR_SUCCESS) {
srs_error("rtsp: decode rtp packet failed. ret=%d", ret); srs_error("rtsp: decode rtp packet failed. ret=%d", ret);
return ret; return ret;
} }
if (pkt.chunked) { if (pkt.chunked) {
if (!cache) { if (!cache) {
cache = new SrsRtpPacket(); cache = new SrsRtpPacket();
@ -102,10 +102,10 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
cache->copy(&pkt); cache->copy(&pkt);
cache->payload->append(pkt.payload->bytes(), pkt.payload->length()); cache->payload->append(pkt.payload->bytes(), pkt.payload->length());
if (!cache->completed && pprint->can_print()) { 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", 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, nb_buf, pprint->age(), cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc,
cache->payload->length() cache->payload->length()
); );
return ret; return ret;
} }
} else { } else {
@ -114,14 +114,14 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
cache->reap(&pkt); cache->reap(&pkt);
} }
} }
if (pprint->can_print()) { 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", 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, stream_id, nb_buf, pprint->age(), cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc,
cache->payload->length(), cache->chunked cache->payload->length(), cache->chunked
); );
} }
// always free it. // always free it.
SrsAutoFree(SrsRtpPacket, cache); 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); srs_error("rtsp: process rtp packet failed. ret=%d", ret);
return ret; return ret;
} }
return ret; return ret;
} }
@ -165,43 +165,43 @@ int64_t SrsRtspJitter::timestamp()
int SrsRtspJitter::correct(int64_t& ts) int SrsRtspJitter::correct(int64_t& ts)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (previous_timestamp == 0) { if (previous_timestamp == 0) {
previous_timestamp = ts; previous_timestamp = ts;
} }
delta = srs_max(0, (int)(ts - previous_timestamp)); delta = srs_max(0, (int)(ts - previous_timestamp));
if (delta > 90000) { if (delta > 90000) {
delta = 0; delta = 0;
} }
previous_timestamp = ts; previous_timestamp = ts;
ts = pts + delta; ts = pts + delta;
pts = ts; pts = ts;
return ret; return ret;
} }
SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o)
{ {
output_template = o; output_template = o;
session = ""; session = "";
video_rtp = NULL; video_rtp = NULL;
audio_rtp = NULL; audio_rtp = NULL;
caster = c; caster = c;
stfd = fd; stfd = fd;
skt = new SrsStSocket(); skt = new SrsStSocket();
rtsp = new SrsRtspStack(skt); rtsp = new SrsRtspStack(skt);
trd = new SrsOneCycleThread("rtsp", this); trd = new SrsOneCycleThread("rtsp", this);
req = NULL; req = NULL;
sdk = NULL; sdk = NULL;
vjitter = new SrsRtspJitter(); vjitter = new SrsRtspJitter();
ajitter = new SrsRtspJitter(); ajitter = new SrsRtspJitter();
avc = new SrsRawH264Stream(); avc = new SrsRawH264Stream();
aac = new SrsRawAacStream(); aac = new SrsRawAacStream();
acodec = new SrsRawAacStreamCodec(); acodec = new SrsRawAacStreamCodec();
@ -213,17 +213,17 @@ SrsRtspConn::~SrsRtspConn()
close(); close();
srs_close_stfd(stfd); srs_close_stfd(stfd);
srs_freep(video_rtp); srs_freep(video_rtp);
srs_freep(audio_rtp); srs_freep(audio_rtp);
srs_freep(trd); srs_freep(trd);
srs_freep(skt); srs_freep(skt);
srs_freep(rtsp); srs_freep(rtsp);
srs_freep(sdk); srs_freep(sdk);
srs_freep(req); srs_freep(req);
srs_freep(vjitter); srs_freep(vjitter);
srs_freep(ajitter); srs_freep(ajitter);
srs_freep(acodec); srs_freep(acodec);
@ -243,11 +243,11 @@ int SrsRtspConn::serve()
int SrsRtspConn::do_cycle() int SrsRtspConn::do_cycle()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// retrieve ip of client. // retrieve ip of client.
std::string ip = srs_get_peer_ip(st_netfd_fileno(stfd)); std::string ip = srs_get_peer_ip(st_netfd_fileno(stfd));
srs_trace("rtsp: serve %s", ip.c_str()); srs_trace("rtsp: serve %s", ip.c_str());
// consume all rtsp messages. // consume all rtsp messages.
for (;;) { for (;;) {
SrsRtspRequest* req = NULL; SrsRtspRequest* req = NULL;
@ -259,7 +259,7 @@ int SrsRtspConn::do_cycle()
} }
SrsAutoFree(SrsRtspRequest, req); SrsAutoFree(SrsRtspRequest, req);
srs_info("rtsp: got rtsp request"); srs_info("rtsp: got rtsp request");
if (req->is_options()) { if (req->is_options()) {
SrsRtspOptionsResponse* res = new SrsRtspOptionsResponse((int)req->seq); SrsRtspOptionsResponse* res = new SrsRtspOptionsResponse((int)req->seq);
res->session = session; res->session = session;
@ -278,7 +278,7 @@ int SrsRtspConn::do_cycle()
rtsp_tcUrl = rtsp_tcUrl.substr(0, pos); rtsp_tcUrl = rtsp_tcUrl.substr(0, pos);
} }
srs_parse_rtmp_url(rtsp_tcUrl, rtsp_tcUrl, rtsp_stream); srs_parse_rtmp_url(rtsp_tcUrl, rtsp_tcUrl, rtsp_stream);
srs_assert(req->sdp); srs_assert(req->sdp);
video_id = ::atoi(req->sdp->video_stream_id.c_str()); video_id = ::atoi(req->sdp->video_stream_id.c_str());
audio_id = ::atoi(req->sdp->audio_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_sps = req->sdp->video_sps;
h264_pps = req->sdp->video_pps; h264_pps = req->sdp->video_pps;
aac_specific_config = req->sdp->audio_sh; aac_specific_config = req->sdp->audio_sh;
srs_trace("rtsp: video(#%d, %s, %s/%s), audio(#%d, %s, %s/%s, %dHZ %dchannels), %s/%s", 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(), 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_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() audio_sample_rate, audio_channel, rtsp_tcUrl.c_str(), rtsp_stream.c_str()
); );
SrsRtspResponse* res = new SrsRtspResponse((int)req->seq); SrsRtspResponse* res = new SrsRtspResponse((int)req->seq);
res->session = session; res->session = session;
if ((ret = rtsp->send_message(res)) != ERROR_SUCCESS) { 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); srs_error("rtsp: alloc port failed. ret=%d", ret);
return ret; return ret;
} }
SrsRtpConn* rtp = NULL; SrsRtpConn* rtp = NULL;
if (req->stream_id == video_id) { if (req->stream_id == video_id) {
srs_freep(video_rtp); 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); srs_error("rtsp: rtp listen at port=%d failed. ret=%d", lpm, ret);
return ret; return ret;
} }
srs_trace("rtsp: #%d %s over %s/%s/%s %s client-port=%d-%d, server-port=%d-%d", 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->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->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, req->transport->cast_type.c_str(), req->transport->client_port_min, req->transport->client_port_max,
lpm, lpm + 1 lpm, lpm + 1
); );
// create session. // create session.
if (session.empty()) { if (session.empty()) {
session = "O9EaZ4bf"; // TODO: FIXME: generate session id. session = "O9EaZ4bf"; // TODO: FIXME: generate session id.
} }
SrsRtspSetupResponse* res = new SrsRtspSetupResponse((int)req->seq); SrsRtspSetupResponse* res = new SrsRtspSetupResponse((int)req->seq);
res->client_port_min = req->transport->client_port_min; res->client_port_min = req->transport->client_port_min;
res->client_port_max = req->transport->client_port_max; res->client_port_max = req->transport->client_port_max;
@ -358,19 +358,19 @@ int SrsRtspConn::do_cycle()
} }
} }
} }
return ret; return ret;
} }
int SrsRtspConn::on_rtp_packet(SrsRtpPacket* pkt, int stream_id) int SrsRtspConn::on_rtp_packet(SrsRtpPacket* pkt, int stream_id)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// ensure rtmp connected. // ensure rtmp connected.
if ((ret = connect()) != ERROR_SUCCESS) { if ((ret = connect()) != ERROR_SUCCESS) {
return ret; return ret;
} }
if (stream_id == video_id) { if (stream_id == video_id) {
// rtsp tbn is ts tbn. // rtsp tbn is ts tbn.
int64_t pts = pkt->timestamp; 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); srs_error("rtsp: correct by jitter failed. ret=%d", ret);
return ret; return ret;
} }
// TODO: FIXME: set dts to pts, please finger out the right dts. // TODO: FIXME: set dts to pts, please finger out the right dts.
int64_t dts = pts; int64_t dts = pts;
return on_rtp_video(pkt, dts, pts); return on_rtp_video(pkt, dts, pts);
} else { } else {
// rtsp tbn is ts tbn. // 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); srs_error("rtsp: correct by jitter failed. ret=%d", ret);
return ret; return ret;
} }
return on_rtp_audio(pkt, pts); return on_rtp_audio(pkt, pts);
} }
return ret; return ret;
} }
@ -416,7 +416,7 @@ int SrsRtspConn::cycle()
if (ret == ERROR_SOCKET_CLOSED) { if (ret == ERROR_SOCKET_CLOSED) {
srs_warn("client disconnect peer. ret=%d", ret); srs_warn("client disconnect peer. ret=%d", ret);
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -425,22 +425,22 @@ void SrsRtspConn::on_thread_stop()
if (video_rtp) { if (video_rtp) {
caster->free_port(video_rtp->port(), video_rtp->port() + 1); caster->free_port(video_rtp->port(), video_rtp->port() + 1);
} }
if (audio_rtp) { if (audio_rtp) {
caster->free_port(audio_rtp->port(), audio_rtp->port() + 1); caster->free_port(audio_rtp->port(), audio_rtp->port() + 1);
} }
caster->remove(this); caster->remove(this);
} }
int SrsRtspConn::on_rtp_video(SrsRtpPacket* pkt, int64_t dts, int64_t pts) int SrsRtspConn::on_rtp_video(SrsRtpPacket* pkt, int64_t dts, int64_t pts)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if ((ret = kickoff_audio_cache(pkt, dts)) != ERROR_SUCCESS) { if ((ret = kickoff_audio_cache(pkt, dts)) != ERROR_SUCCESS) {
return ret; return ret;
} }
char* bytes = pkt->payload->bytes(); char* bytes = pkt->payload->bytes();
int length = pkt->payload->length(); int length = pkt->payload->length();
uint32_t fdts = (uint32_t)(dts / 90); 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) { if ((ret = write_h264_ipb_frame(bytes, length, fdts, fpts)) != ERROR_SUCCESS) {
return ret; return ret;
} }
return ret; return ret;
} }
int SrsRtspConn::on_rtp_audio(SrsRtpPacket* pkt, int64_t dts) int SrsRtspConn::on_rtp_audio(SrsRtpPacket* pkt, int64_t dts)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if ((ret = kickoff_audio_cache(pkt, dts)) != ERROR_SUCCESS) { if ((ret = kickoff_audio_cache(pkt, dts)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// cache current audio to kickoff. // cache current audio to kickoff.
acache->dts = dts; acache->dts = dts;
acache->audio = pkt->audio; acache->audio = pkt->audio;
acache->payload = pkt->payload; acache->payload = pkt->payload;
pkt->audio = NULL; pkt->audio = NULL;
pkt->payload = NULL; pkt->payload = NULL;
return ret; return ret;
} }
int SrsRtspConn::kickoff_audio_cache(SrsRtpPacket* pkt, int64_t dts) int SrsRtspConn::kickoff_audio_cache(SrsRtpPacket* pkt, int64_t dts)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// nothing to kick off. // nothing to kick off.
if (!acache->payload) { if (!acache->payload) {
return ret; return ret;
} }
if (dts - acache->dts > 0 && acache->audio->nb_samples > 0) { if (dts - acache->dts > 0 && acache->audio->nb_samples > 0) {
int64_t delta = (dts - acache->dts) / acache->audio->nb_samples; int64_t delta = (dts - acache->dts) / acache->audio->nb_samples;
for (int i = 0; i < acache->audio->nb_samples; i++) { 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; acache->dts = 0;
srs_freep(acache->audio); srs_freep(acache->audio);
srs_freep(acache->payload); srs_freep(acache->payload);
return ret; return ret;
} }
int SrsRtspConn::write_sequence_header() int SrsRtspConn::write_sequence_header()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// use the current dts. // use the current dts.
int64_t dts = vjitter->timestamp() / 90; int64_t dts = vjitter->timestamp() / 90;
// send video sps/pps // send video sps/pps
if ((ret = write_h264_sps_pps((uint32_t)dts, (uint32_t)dts)) != ERROR_SUCCESS) { if ((ret = write_h264_sps_pps((uint32_t)dts, (uint32_t)dts)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// generate audio sh by audio specific config. // generate audio sh by audio specific config.
if (true) { if (true) {
std::string sh = aac_specific_config; std::string sh = aac_specific_config;
SrsFormat* format = new SrsFormat(); SrsFormat* format = new SrsFormat();
SrsAutoFree(SrsFormat, format); SrsAutoFree(SrsFormat, format);
@ -524,12 +524,12 @@ int SrsRtspConn::write_sequence_header()
} }
SrsAudioCodecConfig* dec = format->acodec; SrsAudioCodecConfig* dec = format->acodec;
acodec->sound_format = SrsAudioCodecIdAAC; acodec->sound_format = SrsAudioCodecIdAAC;
acodec->sound_type = (dec->aac_channels == 2)? SrsAudioChannelsStereo : SrsAudioChannelsMono; acodec->sound_type = (dec->aac_channels == 2)? SrsAudioChannelsStereo : SrsAudioChannelsMono;
acodec->sound_size = SrsAudioSampleBits16bit; acodec->sound_size = SrsAudioSampleBits16bit;
acodec->aac_packet_type = 0; acodec->aac_packet_type = 0;
static int srs_aac_srates[] = { static int srs_aac_srates[] = {
96000, 88200, 64000, 48000, 96000, 88200, 64000, 48000,
44100, 32000, 24000, 22050, 44100, 32000, 24000, 22050,
@ -549,12 +549,12 @@ int SrsRtspConn::write_sequence_header()
default: default:
break; break;
}; };
if ((ret = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), acodec, (uint32_t)dts)) != ERROR_SUCCESS) { if ((ret = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), acodec, (uint32_t)dts)) != ERROR_SUCCESS) {
return ret; return ret;
} }
} }
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) { if ((ret = rtmp_write_packet(SrsFrameTypeVideo, timestamp, flv, nb_flv)) != ERROR_SUCCESS) {
return ret; return ret;
} }
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; 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) { if (nal_unit_type == SrsAvcNaluTypeIDR) {
frame_type = SrsVideoAvcFrameTypeKeyFrame; frame_type = SrsVideoAvcFrameTypeKeyFrame;
} }
std::string ibp; std::string ibp;
if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) { if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) {
return ret; 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 SrsRtspConn::write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
char* data = NULL; char* data = NULL;
int size = 0; int size = 0;
if ((ret = aac->mux_aac2flv(frame, frame_size, codec, dts, &data, &size)) != ERROR_SUCCESS) { 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; SrsSharedPtrMessage* msg = NULL;
if ((ret = srs_rtmp_create_msg(type, timestamp, data, size, sdk->sid(), &msg)) != ERROR_SUCCESS) { 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); srs_error("rtsp: create shared ptr msg failed. ret=%d", ret);
return ret; return ret;
} }
srs_assert(msg); srs_assert(msg);
// send out encoded msg. // send out encoded msg.
if ((ret = sdk->send_and_free_message(msg)) != ERROR_SUCCESS) { if ((ret = sdk->send_and_free_message(msg)) != ERROR_SUCCESS) {
close(); close();
@ -659,7 +659,7 @@ int SrsRtspConn::rtmp_write_packet(char type, uint32_t timestamp, char* data, in
int SrsRtspConn::connect() int SrsRtspConn::connect()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// Ignore when connected. // Ignore when connected.
if (sdk) { if (sdk) {
return ret; return ret;
@ -671,13 +671,13 @@ int SrsRtspConn::connect()
std::string schema, host, vhost, app, param; std::string schema, host, vhost, app, param;
int port; int port;
srs_discovery_tc_url(rtsp_tcUrl, schema, host, vhost, app, port, param); srs_discovery_tc_url(rtsp_tcUrl, schema, host, vhost, app, port, param);
// generate output by template. // generate output by template.
std::string output = output_template; std::string output = output_template;
output = srs_string_replace(output, "[app]", app); output = srs_string_replace(output, "[app]", app);
output = srs_string_replace(output, "[stream]", rtsp_stream); output = srs_string_replace(output, "[stream]", rtsp_stream);
} }
// connect host. // connect host.
int64_t cto = SRS_CONSTS_RTMP_TMMS; int64_t cto = SRS_CONSTS_RTMP_TMMS;
int64_t sto = SRS_CONSTS_RTMP_PULSE_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); srs_error("rtsp: publish %s failed. ret=%d", url.c_str(), ret);
return ret; return ret;
} }
return write_sequence_header(); return write_sequence_header();
} }
@ -726,7 +726,7 @@ SrsRtspCaster::~SrsRtspCaster()
int SrsRtspCaster::alloc_port(int* pport) int SrsRtspCaster::alloc_port(int* pport)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// use a pair of port. // use a pair of port.
for (int i = local_port_min; i < local_port_max - 1; i += 2) { for (int i = local_port_min; i < local_port_max - 1; i += 2) {
if (!used_ports[i]) { if (!used_ports[i]) {
@ -737,7 +737,7 @@ int SrsRtspCaster::alloc_port(int* pport)
} }
} }
srs_info("rtsp: alloc port=%d-%d", *pport, *pport + 1); srs_info("rtsp: alloc port=%d-%d", *pport, *pport + 1);
return ret; return ret;
} }
@ -752,18 +752,18 @@ void SrsRtspCaster::free_port(int lpmin, int lpmax)
int SrsRtspCaster::on_tcp_client(st_netfd_t stfd) int SrsRtspCaster::on_tcp_client(st_netfd_t stfd)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsRtspConn* conn = new SrsRtspConn(this, stfd, output); SrsRtspConn* conn = new SrsRtspConn(this, stfd, output);
if ((ret = conn->serve()) != ERROR_SUCCESS) { if ((ret = conn->serve()) != ERROR_SUCCESS) {
srs_error("rtsp: serve client failed. ret=%d", ret); srs_error("rtsp: serve client failed. ret=%d", ret);
srs_freep(conn); srs_freep(conn);
return ret; return ret;
} }
clients.push_back(conn); clients.push_back(conn);
srs_info("rtsp: start thread to serve client."); srs_info("rtsp: start thread to serve client.");
return ret; return ret;
} }
@ -774,7 +774,7 @@ void SrsRtspCaster::remove(SrsRtspConn* conn)
clients.erase(it); clients.erase(it);
} }
srs_info("rtsp: remove connection from caster."); srs_info("rtsp: remove connection from caster.");
srs_freep(conn); srs_freep(conn);
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_RTSP_HPP #ifndef SRS_APP_RTSP_HPP
#define SRS_APP_RTSP_HPP #define SRS_APP_RTSP_HPP
/*
#include <srs_app_rtsp.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
@ -59,8 +55,8 @@ class SrsPithyPrint;
class SrsSimpleRtmpClient; class SrsSimpleRtmpClient;
/** /**
* a rtp connection which transport a stream. * a rtp connection which transport a stream.
*/ */
class SrsRtpConn: public ISrsUdpHandler class SrsRtpConn: public ISrsUdpHandler
{ {
private: private:
@ -82,21 +78,21 @@ public:
}; };
/** /**
* audio is group by frames. * audio is group by frames.
*/ */
struct SrsRtspAudioCache struct SrsRtspAudioCache
{ {
int64_t dts; int64_t dts;
SrsAudioFrame* audio; SrsAudioFrame* audio;
SrsSimpleStream* payload; SrsSimpleStream* payload;
SrsRtspAudioCache(); SrsRtspAudioCache();
virtual ~SrsRtspAudioCache(); virtual ~SrsRtspAudioCache();
}; };
/** /**
* the time jitter correct for rtsp. * the time jitter correct for rtsp.
*/ */
class SrsRtspJitter class SrsRtspJitter
{ {
private: private:
@ -112,8 +108,8 @@ public:
}; };
/** /**
* the rtsp connection serve the fd. * the rtsp connection serve the fd.
*/ */
class SrsRtspConn : public ISrsOneCycleThreadHandler class SrsRtspConn : public ISrsOneCycleThreadHandler
{ {
private: private:
@ -159,7 +155,7 @@ public:
virtual int serve(); virtual int serve();
private: private:
virtual int do_cycle(); virtual int do_cycle();
// internal methods // internal methods
public: public:
virtual int on_rtp_packet(SrsRtpPacket* pkt, int stream_id); virtual int on_rtp_packet(SrsRtpPacket* pkt, int stream_id);
// interface ISrsOneCycleThreadHandler // interface ISrsOneCycleThreadHandler
@ -184,8 +180,8 @@ private:
}; };
/** /**
* the caster for rtsp. * the caster for rtsp.
*/ */
class SrsRtspCaster : public ISrsTcpHandler class SrsRtspCaster : public ISrsTcpHandler
{ {
private: private:
@ -201,18 +197,18 @@ public:
virtual ~SrsRtspCaster(); virtual ~SrsRtspCaster();
public: public:
/** /**
* alloc a rtp port from local ports pool. * alloc a rtp port from local ports pool.
* @param pport output the rtp port. * @param pport output the rtp port.
*/ */
virtual int alloc_port(int* pport); virtual int alloc_port(int* pport);
/** /**
* free the alloced rtp port. * free the alloced rtp port.
*/ */
virtual void free_port(int lpmin, int lpmax); virtual void free_port(int lpmin, int lpmax);
// interface ISrsTcpHandler // interface ISrsTcpHandler
public: public:
virtual int on_tcp_client(st_netfd_t stfd); virtual int on_tcp_client(st_netfd_t stfd);
// internal methods. // internal methods.
public: public:
virtual void remove(SrsRtspConn* conn); virtual void remove(SrsRtspConn* conn);
}; };

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_security.hpp> #include <srs_app_security.hpp>
@ -77,7 +77,7 @@ int SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std:
if (rule->name != "allow") { if (rule->name != "allow") {
continue; continue;
} }
switch (type) { switch (type) {
case SrsRtmpConnPlay: case SrsRtmpConnPlay:
if (rule->arg0() != "play") { if (rule->arg0() != "play") {
@ -122,7 +122,7 @@ int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::
if (rule->name != "deny") { if (rule->name != "deny") {
continue; continue;
} }
switch (type) { switch (type) {
case SrsRtmpConnPlay: case SrsRtmpConnPlay:
if (rule->arg0() != "play") { if (rule->arg0() != "play") {

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_SECURITY_HPP #ifndef SRS_APP_SECURITY_HPP
#define SRS_APP_SECURITY_HPP #define SRS_APP_SECURITY_HPP
/*
#include <srs_app_security.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>
@ -37,9 +33,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class SrsConfDirective; class SrsConfDirective;
/** /**
* the security apply on vhost. * the security apply on vhost.
* @see https://github.com/ossrs/srs/issues/211 * @see https://github.com/ossrs/srs/issues/211
*/ */
class SrsSecurity class SrsSecurity
{ {
public: public:
@ -47,22 +43,22 @@ public:
virtual ~SrsSecurity(); virtual ~SrsSecurity();
public: public:
/** /**
* security check the client apply by vhost security strategy * security check the client apply by vhost security strategy
* @param type the client type, publish or play. * @param type the client type, publish or play.
* @param ip the ip address of client. * @param ip the ip address of client.
* @param req the request object of client. * @param req the request object of client.
*/ */
virtual int check(SrsRtmpConnType type, std::string ip, SrsRequest* req); virtual int check(SrsRtmpConnType type, std::string ip, SrsRequest* req);
private: private:
/** /**
* security check the allow, * security check the allow,
* @return, if allowed, ERROR_SYSTEM_SECURITY_ALLOW. * @return, if allowed, ERROR_SYSTEM_SECURITY_ALLOW.
*/ */
virtual int allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip); virtual int allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip);
/** /**
* security check the deny, * security check the deny,
* @return, if denied, ERROR_SYSTEM_SECURITY_DENY. * @return, if denied, ERROR_SYSTEM_SECURITY_DENY.
*/ */
virtual int deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip); virtual int deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip);
}; };

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_server.hpp> #include <srs_app_server.hpp>
@ -92,23 +92,23 @@ using namespace std;
// SRS_SYS_CYCLE_INTERVAL * SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES
#define SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES 9 #define SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES 9
std::string srs_listener_type2string(SrsListenerType type) std::string srs_listener_type2string(SrsListenerType type)
{ {
switch (type) { switch (type) {
case SrsListenerRtmpStream: case SrsListenerRtmpStream:
return "RTMP"; return "RTMP";
case SrsListenerHttpApi: case SrsListenerHttpApi:
return "HTTP-API"; return "HTTP-API";
case SrsListenerHttpStream: case SrsListenerHttpStream:
return "HTTP-Server"; return "HTTP-Server";
case SrsListenerMpegTsOverUdp: case SrsListenerMpegTsOverUdp:
return "MPEG-TS over UDP"; return "MPEG-TS over UDP";
case SrsListenerRtsp: case SrsListenerRtsp:
return "RTSP"; return "RTSP";
case SrsListenerFlv: case SrsListenerFlv:
return "HTTP-FLV"; return "HTTP-FLV";
default: default:
return "UNKONWN"; return "UNKONWN";
} }
} }
@ -144,21 +144,21 @@ int SrsBufferListener::listen(string i, int p)
ip = i; ip = i;
port = p; port = p;
srs_freep(listener); srs_freep(listener);
listener = new SrsTcpListener(this, ip, port); listener = new SrsTcpListener(this, ip, port);
if ((ret = listener->listen()) != ERROR_SUCCESS) { if ((ret = listener->listen()) != ERROR_SUCCESS) {
srs_error("tcp listen failed. ret=%d", ret); srs_error("tcp listen failed. ret=%d", ret);
return ret; return ret;
} }
srs_info("listen thread current_cid=%d, " srs_info("listen thread current_cid=%d, "
"listen at port=%d, type=%d, fd=%d started success, ep=%s:%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); _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()); srs_trace("%s listen at tcp://%s:%d, fd=%d", srs_listener_type2string(type).c_str(), ip.c_str(), port, listener->fd());
return ret; return ret;
} }
@ -170,7 +170,7 @@ int SrsBufferListener::on_tcp_client(st_netfd_t stfd)
srs_warn("accept client error. ret=%d", ret); srs_warn("accept client error. ret=%d", ret);
return ret; return 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) SrsRtspListener::SrsRtspListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c) : SrsListener(svr, t)
{ {
listener = NULL; listener = NULL;
// the caller already ensure the type is ok, // the caller already ensure the type is ok,
// we just assert here for unknown stream caster. // we just assert here for unknown stream caster.
srs_assert(type == SrsListenerRtsp); srs_assert(type == SrsListenerRtsp);
@ -196,25 +196,25 @@ SrsRtspListener::~SrsRtspListener()
int SrsRtspListener::listen(string i, int p) int SrsRtspListener::listen(string i, int p)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// the caller already ensure the type is ok, // the caller already ensure the type is ok,
// we just assert here for unknown stream caster. // we just assert here for unknown stream caster.
srs_assert(type == SrsListenerRtsp); srs_assert(type == SrsListenerRtsp);
ip = i; ip = i;
port = p; port = p;
srs_freep(listener); srs_freep(listener);
listener = new SrsTcpListener(this, ip, port); listener = new SrsTcpListener(this, ip, port);
if ((ret = listener->listen()) != ERROR_SUCCESS) { if ((ret = listener->listen()) != ERROR_SUCCESS) {
srs_error("rtsp caster listen failed. ret=%d", ret); srs_error("rtsp caster listen failed. ret=%d", ret);
return 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_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()); srs_trace("%s listen at tcp://%s:%d, fd=%d", srs_listener_type2string(type).c_str(), ip.c_str(), port, listener->fd());
return ret; return ret;
} }
@ -226,7 +226,7 @@ int SrsRtspListener::on_tcp_client(st_netfd_t stfd)
srs_warn("accept client error. ret=%d", ret); srs_warn("accept client error. ret=%d", ret);
return ret; return ret;
} }
return ret; return ret;
} }
@ -305,34 +305,34 @@ SrsUdpStreamListener::~SrsUdpStreamListener()
int SrsUdpStreamListener::listen(string i, int p) int SrsUdpStreamListener::listen(string i, int p)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// the caller already ensure the type is ok, // the caller already ensure the type is ok,
// we just assert here for unknown stream caster. // we just assert here for unknown stream caster.
srs_assert(type == SrsListenerMpegTsOverUdp); srs_assert(type == SrsListenerMpegTsOverUdp);
ip = i; ip = i;
port = p; port = p;
srs_freep(listener); srs_freep(listener);
listener = new SrsUdpListener(caster, ip, port); listener = new SrsUdpListener(caster, ip, port);
if ((ret = listener->listen()) != ERROR_SUCCESS) { if ((ret = listener->listen()) != ERROR_SUCCESS) {
srs_error("udp caster listen failed. ret=%d", ret); srs_error("udp caster listen failed. ret=%d", ret);
return ret; return ret;
} }
srs_info("listen thread current_cid=%d, " srs_info("listen thread current_cid=%d, "
"listen at port=%d, type=%d, fd=%d started success, ep=%s:%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); _srs_context->get_id(), p, type, listener->fd(), i.c_str(), p);
// notify the handler the fd changed. // notify the handler the fd changed.
if ((ret = caster->on_stfd_change(listener->stfd())) != ERROR_SUCCESS) { if ((ret = caster->on_stfd_change(listener->stfd())) != ERROR_SUCCESS) {
srs_error("notify handler fd changed. ret=%d", ret); srs_error("notify handler fd changed. ret=%d", ret);
return 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()); srs_trace("%s listen at udp://%s:%d, fd=%d", srs_listener_type2string(type).c_str(), ip.c_str(), port, listener->fd());
return ret; return ret;
} }
@ -430,7 +430,7 @@ int SrsSignalManager::start()
sigaction(SRS_SIGNAL_REOPEN_LOG, &sa, NULL); sigaction(SRS_SIGNAL_REOPEN_LOG, &sa, NULL);
srs_trace("signal installed, reload=%d, reopen=%d, grace_quit=%d", 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(); return pthread->start();
} }
@ -438,7 +438,7 @@ int SrsSignalManager::start()
int SrsSignalManager::cycle() int SrsSignalManager::cycle()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
int signo; int signo;
/* Read the next signal from the pipe */ /* Read the next signal from the pipe */
@ -511,7 +511,7 @@ void SrsServer::destroy()
srs_freep(http_api_mux); srs_freep(http_api_mux);
srs_freep(http_server); srs_freep(http_server);
srs_freep(http_heartbeat); srs_freep(http_heartbeat);
#ifdef SRS_AUTO_INGEST #ifdef SRS_AUTO_INGEST
srs_freep(ingester); srs_freep(ingester);
#endif #endif
@ -546,7 +546,7 @@ void SrsServer::dispose()
SrsSource::dispose_all(); SrsSource::dispose_all();
// @remark don't dispose all connections, for too slow. // @remark don't dispose all connections, for too slow.
#ifdef SRS_AUTO_MEM_WATCH #ifdef SRS_AUTO_MEM_WATCH
srs_memory_report(); srs_memory_report();
#endif #endif
@ -582,12 +582,12 @@ int SrsServer::initialize(ISrsServerCycle* cycle_handler)
} }
http_heartbeat = new SrsHttpHeartbeat(); http_heartbeat = new SrsHttpHeartbeat();
#ifdef SRS_AUTO_INGEST #ifdef SRS_AUTO_INGEST
srs_assert(!ingester); srs_assert(!ingester);
ingester = new SrsIngester(); ingester = new SrsIngester();
#endif #endif
return ret; return ret;
} }
@ -604,7 +604,7 @@ int SrsServer::initialize_st()
// @remark, st alloc segment use mmap, which only support 32757 threads, // @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. // 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. // 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) { if (_srs_config->get_max_connections() > __MMAP_MAX_CONNECTIONS) {
ret = ERROR_ST_EXCEED_THREADS; ret = ERROR_ST_EXCEED_THREADS;
srs_error("st mmap for stack allocation must <= %d threads, " srs_error("st mmap for stack allocation must <= %d threads, "
@ -632,7 +632,7 @@ int SrsServer::initialize_st()
return ret; return ret;
} }
srs_trace("server main cid=%d, pid=%d, ppid=%d, asprocess=%d", 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; return ret;
} }
@ -653,7 +653,7 @@ int SrsServer::acquire_pid_file()
std::string pid_file = _srs_config->get_pid_file(); std::string pid_file = _srs_config->get_pid_file();
// -rw-r--r-- // -rw-r--r--
// 644 // 644
int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
@ -667,7 +667,7 @@ int SrsServer::acquire_pid_file()
// require write lock // require write lock
struct flock lock; struct flock lock;
lock.l_type = F_WRLCK; // F_RDLCK, F_WRLCK, F_UNLCK lock.l_type = F_WRLCK; // F_RDLCK, F_WRLCK, F_UNLCK
lock.l_start = 0; // type offset, relative to l_whence lock.l_start = 0; // type offset, relative to l_whence
lock.l_whence = SEEK_SET; // SEEK_SET, SEEK_CUR, SEEK_END 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); srs_error("require lock for file %s error! ret=%#x", pid_file.c_str(), ret);
return ret; return ret;
} }
// truncate file // truncate file
if (ftruncate(fd, 0) < 0) { if (ftruncate(fd, 0) < 0) {
ret = ERROR_SYSTEM_PID_TRUNCATE_FILE; 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); srs_error("write our pid error! pid=%s file=%s ret=%#x", pid.c_str(), pid_file.c_str(), ret);
return ret; return ret;
} }
// auto close when fork child process. // auto close when fork child process.
int val; int val;
if ((val = fcntl(fd, F_GETFD, 0)) < 0) { if ((val = fcntl(fd, F_GETFD, 0)) < 0) {
@ -825,7 +825,7 @@ int SrsServer::http_handle()
return ret; return ret;
} }
srs_trace("http: api mount /console to %s", dir.c_str()); srs_trace("http: api mount /console to %s", dir.c_str());
return ret; return ret;
} }
@ -839,16 +839,16 @@ int SrsServer::ingest()
return ret; return ret;
} }
#endif #endif
return ret; return ret;
} }
int SrsServer::cycle() int SrsServer::cycle()
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
ret = do_cycle(); ret = do_cycle();
#ifdef SRS_AUTO_GPERF_MC #ifdef SRS_AUTO_GPERF_MC
destroy(); destroy();
@ -874,7 +874,7 @@ int SrsServer::cycle()
void SrsServer::on_signal(int signo) void SrsServer::on_signal(int signo)
{ {
if (signo == SRS_SIGNAL_RELOAD) { if (signo == SRS_SIGNAL_RELOAD) {
signal_reload = true; signal_reload = true;
return; return;
@ -949,7 +949,7 @@ int SrsServer::do_cycle()
srs_error("cycle handle failed. ret=%d", ret); srs_error("cycle handle failed. ret=%d", ret);
return ret; return ret;
} }
// the interval in config. // the interval in config.
int heartbeat_max_resolution = (int)(_srs_config->get_heartbeat_interval() / SRS_SYS_CYCLE_INTERVAL); 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."); srs_trace("cleanup for gracefully terminate.");
return ret; return ret;
} }
// for gperf heap checker, // for gperf heap checker,
// @see: research/gperftools/heap-checker/heap_checker.cc // @see: research/gperftools/heap-checker/heap_checker.cc
// if user interrupt the program, exit to check mem leak. // 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."); srs_trace("persistence config to file success.");
} }
// do reload the config. // do reload the config.
if (signal_reload) { if (signal_reload) {
signal_reload = false; signal_reload = false;
@ -1058,7 +1058,7 @@ int SrsServer::do_cycle()
srs_info("server main thread loop"); srs_info("server main thread loop");
} }
} }
return ret; return ret;
} }
@ -1146,15 +1146,15 @@ int SrsServer::listen_stream_caster()
std::vector<SrsConfDirective*>::iterator it; std::vector<SrsConfDirective*>::iterator it;
std::vector<SrsConfDirective*> stream_casters = _srs_config->get_stream_casters(); std::vector<SrsConfDirective*> stream_casters = _srs_config->get_stream_casters();
for (it = stream_casters.begin(); it != stream_casters.end(); ++it) { for (it = stream_casters.begin(); it != stream_casters.end(); ++it) {
SrsConfDirective* stream_caster = *it; SrsConfDirective* stream_caster = *it;
if (!_srs_config->get_stream_caster_enabled(stream_caster)) { if (!_srs_config->get_stream_caster_enabled(stream_caster)) {
continue; continue;
} }
SrsListener* listener = NULL; SrsListener* listener = NULL;
std::string caster = _srs_config->get_stream_caster_engine(stream_caster); std::string caster = _srs_config->get_stream_caster_engine(stream_caster);
if (srs_stream_caster_is_udp(caster)) { if (srs_stream_caster_is_udp(caster)) {
listener = new SrsUdpCasterListener(this, SrsListenerMpegTsOverUdp, stream_caster); listener = new SrsUdpCasterListener(this, SrsListenerMpegTsOverUdp, stream_caster);
@ -1168,7 +1168,7 @@ int SrsServer::listen_stream_caster()
return ret; return ret;
} }
srs_assert(listener != NULL); srs_assert(listener != NULL);
listeners.push_back(listener); listeners.push_back(listener);
int port = _srs_config->get_stream_caster_listen(stream_caster); int port = _srs_config->get_stream_caster_listen(stream_caster);
@ -1219,7 +1219,7 @@ void SrsServer::resample_kbps()
} }
// TODO: FXME: support all other connections. // TODO: FXME: support all other connections.
// sample the kbps, get the stat. // sample the kbps, get the stat.
SrsKbps* kbps = stat->kbps_sample(); 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); srs_info("ignore empty ip client, fd=%d.", fd);
return NULL; return NULL;
} }
// check connection limitation. // check connection limitation.
int max_connections = _srs_config->get_max_connections(); int max_connections = _srs_config->get_max_connections();
if (handler && (ret = handler->on_accept_client(max_connections, (int)conns.size()) != ERROR_SUCCESS)) { 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) { if ((ret = on_reload_vhost_http_updated()) != ERROR_SUCCESS) {
return ret; return ret;
} }
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) { if ((ret = on_reload_vhost_http_updated()) != ERROR_SUCCESS) {
return ret; return ret;
} }
return ret; return ret;
} }

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_SERVER_HPP #ifndef SRS_APP_SERVER_HPP
#define SRS_APP_SERVER_HPP #define SRS_APP_SERVER_HPP
/*
#include <srs_app_server.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <vector> #include <vector>
@ -61,7 +57,7 @@ class SrsKafkaProducer;
// listener type for server to identify the connection, // listener type for server to identify the connection,
// that is, use different type to process the connection. // that is, use different type to process the connection.
enum SrsListenerType enum SrsListenerType
{ {
// RTMP client, // RTMP client,
SrsListenerRtmpStream = 0, 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 class SrsListener
{ {
protected: protected:
@ -97,8 +93,8 @@ public:
}; };
/** /**
* tcp listener. * tcp listener.
*/ */
class SrsBufferListener : virtual public SrsListener, virtual public ISrsTcpHandler class SrsBufferListener : virtual public SrsListener, virtual public ISrsTcpHandler
{ {
private: private:
@ -108,15 +104,15 @@ public:
virtual ~SrsBufferListener(); virtual ~SrsBufferListener();
public: public:
virtual int listen(std::string ip, int port); virtual int listen(std::string ip, int port);
// ISrsTcpHandler // ISrsTcpHandler
public: public:
virtual int on_tcp_client(st_netfd_t stfd); virtual int on_tcp_client(st_netfd_t stfd);
}; };
#ifdef SRS_AUTO_STREAM_CASTER #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 class SrsRtspListener : virtual public SrsListener, virtual public ISrsTcpHandler
{ {
private: private:
@ -127,7 +123,7 @@ public:
virtual ~SrsRtspListener(); virtual ~SrsRtspListener();
public: public:
virtual int listen(std::string i, int p); virtual int listen(std::string i, int p);
// ISrsTcpHandler // ISrsTcpHandler
public: public:
virtual int on_tcp_client(st_netfd_t stfd); virtual int on_tcp_client(st_netfd_t stfd);
}; };
@ -145,7 +141,7 @@ public:
virtual ~SrsHttpFlvListener(); virtual ~SrsHttpFlvListener();
public: public:
virtual int listen(std::string i, int p); virtual int listen(std::string i, int p);
// ISrsTcpHandler // ISrsTcpHandler
public: public:
virtual int on_tcp_client(st_netfd_t stfd); virtual int on_tcp_client(st_netfd_t stfd);
}; };
@ -179,9 +175,9 @@ public:
#endif #endif
/** /**
* convert signal to io, * convert signal to io,
* @see: st-1.9/docs/notes.html * @see: st-1.9/docs/notes.html
*/ */
class SrsSignalManager : public ISrsEndlessThreadHandler class SrsSignalManager : public ISrsEndlessThreadHandler
{ {
private: 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 class ISrsServerCycle
{ {
public: public:
ISrsServerCycle(); ISrsServerCycle();
virtual ~ISrsServerCycle(); virtual ~ISrsServerCycle();
public: public:
/** /**
* initialize the cycle handler. * initialize the cycle handler.
*/ */
virtual int initialize() = 0; virtual int initialize() = 0;
/** /**
* do on_cycle while server doing cycle. * do on_cycle while server doing cycle.
*/ */
virtual int on_cycle() = 0; virtual int on_cycle() = 0;
/** /**
* callback the handler when got client. * callback the handler when got client.
@ -233,12 +229,12 @@ public:
}; };
/** /**
* SRS RTMP server, initialize and listen, * SRS RTMP server, initialize and listen,
* start connection service thread, destroy client. * start connection service thread, destroy client.
*/ */
class SrsServer : virtual public ISrsReloadHandler class SrsServer : virtual public ISrsReloadHandler
, virtual public ISrsSourceHandler , virtual public ISrsSourceHandler
, virtual public IConnectionManager , virtual public IConnectionManager
{ {
private: private:
// TODO: FIXME: rename to http_api // TODO: FIXME: rename to http_api
@ -250,31 +246,31 @@ private:
#endif #endif
private: private:
/** /**
* the pid file fd, lock the file write when server is running. * 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, * @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 * 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. * maybe valid but the process is not SRS, the init.d script will never start server.
*/ */
int pid_fd; int pid_fd;
/** /**
* all connections, connection manager * all connections, connection manager
*/ */
std::vector<SrsConnection*> conns; std::vector<SrsConnection*> conns;
/** /**
* all listners, listener manager. * all listners, listener manager.
*/ */
std::vector<SrsListener*> listeners; std::vector<SrsListener*> listeners;
/** /**
* signal manager which convert gignal to io message. * signal manager which convert gignal to io message.
*/ */
SrsSignalManager* signal_manager; SrsSignalManager* signal_manager;
/** /**
* handle in server cycle. * handle in server cycle.
*/ */
ISrsServerCycle* handler; ISrsServerCycle* handler;
/** /**
* user send the signal, convert to variable. * user send the signal, convert to variable.
*/ */
bool signal_reload; bool signal_reload;
bool signal_persistence_config; bool signal_persistence_config;
bool signal_gmc_stop; bool signal_gmc_stop;
@ -286,17 +282,17 @@ public:
virtual ~SrsServer(); virtual ~SrsServer();
private: private:
/** /**
* the destroy is for gmc to analysis the memory leak, * the destroy is for gmc to analysis the memory leak,
* if not destroy global/static data, the gmc will warning memory leak. * if not destroy global/static data, the gmc will warning memory leak.
* in service, server never destroy, directly exit when restart. * in service, server never destroy, directly exit when restart.
*/ */
virtual void destroy(); 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. * to stop all ingesters, cleanup HLS and dvr.
*/ */
virtual void dispose(); virtual void dispose();
// server startup workflow, @see run_master() // server startup workflow, @see run_master()
public: public:
/** /**
* initialize server with callback handler. * initialize server with callback handler.
@ -311,7 +307,7 @@ public:
virtual int http_handle(); virtual int http_handle();
virtual int ingest(); virtual int ingest();
virtual int cycle(); virtual int cycle();
// server utilities. // server utilities.
public: public:
/** /**
* callback for signal manager got a signal. * callback for signal manager got a signal.
@ -330,39 +326,39 @@ public:
virtual void on_signal(int signo); virtual void on_signal(int signo);
private: private:
/** /**
* the server thread main cycle, * the server thread main cycle,
* update the global static data, for instance, the current time, * update the global static data, for instance, the current time,
* the cpu/mem/network statistic. * the cpu/mem/network statistic.
*/ */
virtual int do_cycle(); virtual int do_cycle();
/** /**
* listen at specified protocol. * listen at specified protocol.
*/ */
virtual int listen_rtmp(); virtual int listen_rtmp();
virtual int listen_http_api(); virtual int listen_http_api();
virtual int listen_http_stream(); virtual int listen_http_stream();
virtual int listen_stream_caster(); virtual int listen_stream_caster();
/** /**
* close the listeners for specified type, * close the listeners for specified type,
* remove the listen object from manager. * remove the listen object from manager.
*/ */
virtual void close_listeners(SrsListenerType type); virtual void close_listeners(SrsListenerType type);
/** /**
* resample the server kbs. * resample the server kbs.
*/ */
virtual void resample_kbps(); virtual void resample_kbps();
// internal only // internal only
public: public:
/** /**
* when listener got a fd, notice server to accept it. * when listener got a fd, notice server to accept it.
* @param type, the client type, used to create concrete connection, * @param type, the client type, used to create concrete connection,
* for instance RTMP connection to serve client. * for instance RTMP connection to serve client.
* @param stfd, the client fd in st boxed, the underlayer fd. * @param stfd, the client fd in st boxed, the underlayer fd.
*/ */
virtual int accept_client(SrsListenerType type, st_netfd_t stfd); virtual int accept_client(SrsListenerType type, st_netfd_t stfd);
private: private:
virtual SrsConnection* fd2conn(SrsListenerType type, st_netfd_t stfd); virtual SrsConnection* fd2conn(SrsListenerType type, st_netfd_t stfd);
// IConnectionManager // IConnectionManager
public: public:
/** /**
* callback for connection to remove itself. * callback for connection to remove itself.

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_source.hpp> #include <srs_app_source.hpp>
@ -95,7 +95,7 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag)
if (ag == SrsRtmpJitterAlgorithmOFF) { if (ag == SrsRtmpJitterAlgorithmOFF) {
return ret; return ret;
} }
// start at zero, but donot ensure monotonically increasing. // start at zero, but donot ensure monotonically increasing.
if (ag == SrsRtmpJitterAlgorithmZERO) { if (ag == SrsRtmpJitterAlgorithmZERO) {
// for the first time, last_pkt_correct_time is -1. // 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: * we use a very simple time jitter detect/correct algorithm:
* 1. delta: ensure the delta is positive and valid, * 1. delta: ensure the delta is positive and valid,
* we set the delta to DEFAULT_FRAME_TIME_MS, * we set the delta to DEFAULT_FRAME_TIME_MS,
* if the delta of time is nagative or greater than CONST_MAX_JITTER_MS. * if the delta of time is nagative or greater than CONST_MAX_JITTER_MS.
* 2. last_pkt_time: specifies the original packet time, * 2. last_pkt_time: specifies the original packet time,
* is used to detect next jitter. * is used to detect next jitter.
* 3. last_pkt_correct_time: simply add the positive delta, * 3. last_pkt_correct_time: simply add the positive delta,
* and enforce the time monotonically. * and enforce the time monotonically.
*/ */
int64_t time = msg->timestamp; int64_t time = msg->timestamp;
int64_t delta = time - last_pkt_time; int64_t delta = time - last_pkt_time;
// if jitter detected, reset the delta. // if jitter detected, reset the delta.
if (delta < CONST_MAX_JITTER_MS_NEG || delta > CONST_MAX_JITTER_MS) { if (delta < CONST_MAX_JITTER_MS_NEG || delta > CONST_MAX_JITTER_MS) {
// use default 10ms to notice the problem of stream. // 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; delta = DEFAULT_FRAME_TIME_MS;
srs_info("jitter detected, last_pts=%"PRId64", pts=%"PRId64", diff=%"PRId64", last_time=%"PRId64", time=%"PRId64", diff=%"PRId64"", 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 { } else {
srs_verbose("timestamp no jitter. time=%"PRId64", last_pkt=%"PRId64", correct_to=%"PRId64"", srs_verbose("timestamp no jitter. time=%"PRId64", last_pkt=%"PRId64", correct_to=%"PRId64"",
time, last_pkt_time, last_pkt_correct_time + delta); time, last_pkt_time, last_pkt_correct_time + delta);
} }
last_pkt_correct_time = srs_max(0, 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); msgs.push_back(msg);
while (av_end_time - av_start_time > queue_size_ms) { while (av_end_time - av_start_time > queue_size_ms) {
// notice the caller queue already overflow and shrinked. // notice the caller queue already overflow and shrinked.
if (is_overflow) { if (is_overflow) {
@ -308,7 +308,7 @@ int SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, in
srs_assert(max_count > 0); srs_assert(max_count > 0);
count = srs_min(max_count, nb_msgs); count = srs_min(max_count, nb_msgs);
SrsSharedPtrMessage** omsgs = msgs.data(); SrsSharedPtrMessage** omsgs = msgs.data();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
pmsgs[i] = omsgs[i]; pmsgs[i] = omsgs[i];
@ -339,7 +339,7 @@ int SrsMessageQueue::dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitter
if (nb_msgs <= 0) { if (nb_msgs <= 0) {
return ret; return ret;
} }
SrsSharedPtrMessage** omsgs = msgs.data(); SrsSharedPtrMessage** omsgs = msgs.data();
for (int i = 0; i < nb_msgs; i++) { for (int i = 0; i < nb_msgs; i++) {
SrsSharedPtrMessage* msg = omsgs[i]; SrsSharedPtrMessage* msg = omsgs[i];
@ -361,7 +361,7 @@ void SrsMessageQueue::shrink()
// igone the sequence header // igone the sequence header
for (int i = 0; i < (int)msgs.size(); i++) { for (int i = 0; i < (int)msgs.size(); i++) {
SrsSharedPtrMessage* msg = msgs.at(i); SrsSharedPtrMessage* msg = msgs.at(i);
if (msg->is_video() && SrsFlvVideo::sh(msg->payload, msg->size)) { if (msg->is_video() && SrsFlvVideo::sh(msg->payload, msg->size)) {
srs_freep(video_sh); srs_freep(video_sh);
video_sh = msg; video_sh = msg;
@ -372,11 +372,11 @@ void SrsMessageQueue::shrink()
audio_sh = msg; audio_sh = msg;
continue; continue;
} }
srs_freep(msg); srs_freep(msg);
} }
msgs.clear(); msgs.clear();
// update av_start_time // update av_start_time
av_start_time = av_end_time; av_start_time = av_end_time;
//push_back secquence header and update timestamp //push_back secquence header and update timestamp
@ -390,11 +390,11 @@ void SrsMessageQueue::shrink()
} }
if (_ignore_shrink) { if (_ignore_shrink) {
srs_info("shrink the cache queue, size=%d, removed=%d, max=%.2f", 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); (int)msgs.size(), msgs_size - (int)msgs.size(), queue_size_ms / 1000.0);
} else { } else {
srs_trace("shrink the cache queue, size=%d, removed=%d, max=%.2f", 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); (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 #ifndef SRS_PERF_QUEUE_FAST_VECTOR
std::vector<SrsSharedPtrMessage*>::iterator it; std::vector<SrsSharedPtrMessage*>::iterator it;
for (it = msgs.begin(); it != msgs.end(); ++it) { for (it = msgs.begin(); it != msgs.end(); ++it) {
SrsSharedPtrMessage* msg = *it; SrsSharedPtrMessage* msg = *it;
srs_freep(msg); srs_freep(msg);
@ -410,7 +410,7 @@ void SrsMessageQueue::clear()
#else #else
msgs.free(); msgs.free();
#endif #endif
msgs.clear(); msgs.clear();
av_start_time = av_end_time = -1; av_start_time = av_end_time = -1;
@ -472,7 +472,7 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitte
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsSharedPtrMessage* msg = shared_msg->copy(); SrsSharedPtrMessage* msg = shared_msg->copy();
if (!atc) { if (!atc) {
if ((ret = jitter->correct(msg, ag)) != ERROR_SUCCESS) { if ((ret = jitter->correct(msg, ag)) != ERROR_SUCCESS) {
srs_freep(msg); srs_freep(msg);
@ -485,9 +485,9 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitte
} }
#ifdef SRS_PERF_QUEUE_COND_WAIT #ifdef SRS_PERF_QUEUE_COND_WAIT
srs_verbose("enqueue msg, time=%"PRId64", size=%d, duration=%d, waiting=%d, min_msg=%d", 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); msg->timestamp, msg->size, queue->duration(), mw_waiting, mw_min_msgs);
// fire the mw when msgs is enough. // fire the mw when msgs is enough.
if (mw_waiting) { if (mw_waiting) {
int duration_ms = queue->duration(); int duration_ms = queue->duration();
@ -537,7 +537,7 @@ int SrsConsumer::dump_packets(SrsMessageArray* msgs, int& count)
if (paused) { if (paused) {
return ret; return ret;
} }
// pump msgs from queue. // pump msgs from queue.
if ((ret = queue->dump_packets(max, msgs->msgs, count)) != ERROR_SUCCESS) { if ((ret = queue->dump_packets(max, msgs->msgs, count)) != ERROR_SUCCESS) {
return ret; return ret;
@ -553,10 +553,10 @@ void SrsConsumer::wait(int nb_msgs, int duration)
st_usleep(SRS_CONSTS_RTMP_PULSE_TMMS); st_usleep(SRS_CONSTS_RTMP_PULSE_TMMS);
return; return;
} }
mw_min_msgs = nb_msgs; mw_min_msgs = nb_msgs;
mw_duration = duration; mw_duration = duration;
int duration_ms = queue->duration(); int duration_ms = queue->duration();
bool match_min_msgs = queue->size() > mw_min_msgs; 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."); srs_verbose("gop cache is disabled.");
return ret; return ret;
} }
// the gop cache know when to gop it. // the gop cache know when to gop it.
SrsSharedPtrMessage* msg = shared_msg; SrsSharedPtrMessage* msg = shared_msg;
@ -673,8 +673,8 @@ int SrsGopCache::cache(SrsSharedPtrMessage* shared_msg)
// clear gop cache when got key frame // clear gop cache when got key frame
if (msg->is_video() && SrsFlvVideo::keyframe(msg->payload, msg->size)) { if (msg->is_video() && SrsFlvVideo::keyframe(msg->payload, msg->size)) {
srs_info("clear gop cache when got keyframe. vcount=%d, count=%d", 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(); clear();
// curent msg is video frame, so we set to 1. // curent msg is video frame, so we set to 1.
@ -695,11 +695,11 @@ void SrsGopCache::clear()
srs_freep(msg); srs_freep(msg);
} }
gop_cache.clear(); gop_cache.clear();
cached_video_count = 0; cached_video_count = 0;
audio_after_last_video_count = 0; audio_after_last_video_count = 0;
} }
int SrsGopCache::dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm) int SrsGopCache::dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm)
{ {
int ret = ERROR_SUCCESS; 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)", 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, 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], c->audio_data_rate / 1000, srs_aac_srates[c->aac_sample_rate],
flv_sample_sizes[c->sound_size], flv_sound_types[c->sound_type], flv_sample_sizes[c->sound_size], flv_sound_types[c->sound_type],
srs_flv_srates[c->sound_rate]); srs_flv_srates[c->sound_rate]);
} }
if ((ret = hls->on_audio(msg, format)) != ERROR_SUCCESS) { 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)", 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(), msg->size, c->id, srs_avc_profile2str(c->avc_profile).c_str(),
srs_avc_level2str(c->avc_level).c_str(), c->width, c->height, srs_avc_level2str(c->avc_level).c_str(), c->width, c->height,
c->video_data_rate / 1000, c->frame_rate, c->duration); c->video_data_rate / 1000, c->frame_rate, c->duration);
} }
if ((ret = hls->on_video(msg, format)) != ERROR_SUCCESS) { 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. // should always not exists for create a source.
srs_assert (pool.find(stream_url) == pool.end()); srs_assert (pool.find(stream_url) == pool.end());
source = new SrsSource(); source = new SrsSource();
if ((ret = source->initialize(r, h)) != ERROR_SUCCESS) { if ((ret = source->initialize(r, h)) != ERROR_SUCCESS) {
srs_freep(source); srs_freep(source);
return ret; return ret;
} }
pool[stream_url] = source; pool[stream_url] = source;
srs_info("create new source for url=%s, vhost=%s", stream_url.c_str(), vhost.c_str()); 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()) { if (pool.find(stream_url) == pool.end()) {
return NULL; return NULL;
} }
source = pool[stream_url]; 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, // for origin auth is on, the token in request maybe invalid,
// and we only need to update the token of request, it's simple. // and we only need to update the token of request, it's simple.
source->req->update_auth(r); source->req->update_auth(r);
return source; return source;
} }
@ -1877,7 +1877,7 @@ SrsSource::~SrsSource()
{ {
_srs_config->unsubscribe(this); _srs_config->unsubscribe(this);
// never free the consumers, // never free the consumers,
// for all consumers are auto free. // for all consumers are auto free.
consumers.clear(); consumers.clear();
@ -1889,7 +1889,7 @@ SrsSource::~SrsSource()
srs_freep(publish_edge); srs_freep(publish_edge);
srs_freep(gop_cache); srs_freep(gop_cache);
srs_freep(aggregate_stream); srs_freep(aggregate_stream);
srs_freep(req); srs_freep(req);
} }
@ -1936,7 +1936,7 @@ int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h)
srs_assert(h); srs_assert(h);
srs_assert(!req); srs_assert(!req);
handler = h; handler = h;
req = r->copy(); req = r->copy();
atc = _srs_config->get_atc(req->vhost); 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) { if ((ret = hub->initialize(this, req)) != ERROR_SUCCESS) {
return ret; return ret;
} }
if ((ret = play_edge->initialize(this, req)) != ERROR_SUCCESS) { if ((ret = play_edge->initialize(this, req)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -2085,7 +2085,7 @@ bool SrsSource::can_publish(bool is_edge)
if (is_edge) { if (is_edge) {
return publish_edge->can_publish(); return publish_edge->can_publish();
} }
return _can_publish; return _can_publish;
} }
@ -2216,7 +2216,7 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg)
if ((ret = hub->on_audio(msg)) != ERROR_SUCCESS) { if ((ret = hub->on_audio(msg)) != ERROR_SUCCESS) {
return ret; return ret;
} }
// cache the sequence header of aac, or first packet of mp3. // 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. // for example, the mp3 is used for hls to write the "right" audio codec.
// TODO: FIXME: to refine the stream info system. // TODO: FIXME: to refine the stream info system.
@ -2352,7 +2352,7 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg)
if (is_sequence_header) { if (is_sequence_header) {
return ret; return ret;
} }
// cache the last gop packets // cache the last gop packets
if ((ret = gop_cache->cache(msg)) != ERROR_SUCCESS) { if ((ret = gop_cache->cache(msg)) != ERROR_SUCCESS) {
srs_error("gop cache msg failed. ret=%d", ret); 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.timestamp = timestamp;
o.header.stream_id = stream_id; o.header.stream_id = stream_id;
o.header.perfer_cid = msg->header.perfer_cid; o.header.perfer_cid = msg->header.perfer_cid;
if (data_size > 0) { if (data_size > 0) {
o.size = data_size; o.size = data_size;
o.payload = new char[o.size]; o.payload = new char[o.size];
@ -2465,7 +2465,7 @@ int SrsSource::on_aggregate(SrsCommonMessage* msg)
return ret; return ret;
} }
stream->read_4bytes(); stream->read_4bytes();
// process parsed message // process parsed message
if (o.header.is_audio()) { if (o.header.is_audio()) {
if ((ret = on_audio(&o)) != ERROR_SUCCESS) { if ((ret = on_audio(&o)) != ERROR_SUCCESS) {
@ -2507,7 +2507,7 @@ int SrsSource::on_publish()
if ((ret = hub->on_publish()) != ERROR_SUCCESS) { if ((ret = hub->on_publish()) != ERROR_SUCCESS) {
return ret; return ret;
} }
// notify the handler. // notify the handler.
srs_assert(handler); srs_assert(handler);
if ((ret = handler->on_publish(this, req)) != ERROR_SUCCESS) { if ((ret = handler->on_publish(this, req)) != ERROR_SUCCESS) {
@ -2529,7 +2529,7 @@ void SrsSource::on_unpublish()
// Notify the hub about the unpublish event. // Notify the hub about the unpublish event.
hub->on_unpublish(); hub->on_unpublish();
// only clear the gop cache, // only clear the gop cache,
// donot clear the sequence header, for it maybe not changed, // donot clear the sequence header, for it maybe not changed,
// when drop dup sequence header, drop the metadata also. // when drop dup sequence header, drop the metadata also.
@ -2540,7 +2540,7 @@ void SrsSource::on_unpublish()
_can_publish = true; _can_publish = true;
_source_id = -1; _source_id = -1;
// notify the handler. // notify the handler.
srs_assert(handler); srs_assert(handler);
SrsStatistic* stat = SrsStatistic::instance(); SrsStatistic* stat = SrsStatistic::instance();
@ -2592,7 +2592,7 @@ int SrsSource::create_consumer(SrsConnection* conn, SrsConsumer*& consumer, bool
} else { } else {
srs_trace("create consumer, ignore gop cache, jitter=%d", jitter_algorithm); srs_trace("create consumer, ignore gop cache, jitter=%d", jitter_algorithm);
} }
// for edge, when play edge stream, check the state // for edge, when play edge stream, check the state
if (_srs_config->get_vhost_is_edge(req->vhost)) { if (_srs_config->get_vhost_is_edge(req->vhost)) {
// notice edge to start for the first client. // notice edge to start for the first client.

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_SOURCE_HPP #ifndef SRS_APP_SOURCE_HPP
#define SRS_APP_SOURCE_HPP #define SRS_APP_SOURCE_HPP
/*
#include <srs_app_source.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <map> #include <map>
@ -67,11 +63,11 @@ class SrsHds;
#endif #endif
/** /**
* the time jitter algorithm: * the time jitter algorithm:
* 1. full, to ensure stream start at zero, and ensure stream monotonically increasing. * 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
* 2. zero, only ensure sttream start at zero, ignore timestamp jitter. * 2. zero, only ensure sttream start at zero, ignore timestamp jitter.
* 3. off, disable the time jitter algorithm, like atc. * 3. off, disable the time jitter algorithm, like atc.
*/ */
enum SrsRtmpJitterAlgorithm enum SrsRtmpJitterAlgorithm
{ {
SrsRtmpJitterAlgorithmFULL = 0x01, SrsRtmpJitterAlgorithmFULL = 0x01,
@ -81,9 +77,9 @@ enum SrsRtmpJitterAlgorithm
int _srs_time_jitter_string2int(std::string time_jitter); int _srs_time_jitter_string2int(std::string time_jitter);
/** /**
* time jitter detect and correct, * time jitter detect and correct,
* to ensure the rtmp stream is monotonically. * to ensure the rtmp stream is monotonically.
*/ */
class SrsRtmpJitter class SrsRtmpJitter
{ {
private: private:
@ -94,22 +90,22 @@ public:
virtual ~SrsRtmpJitter(); virtual ~SrsRtmpJitter();
public: public:
/** /**
* detect the time jitter and correct it. * detect the time jitter and correct it.
* @param ag the algorithm to use for time jitter. * @param ag the algorithm to use for time jitter.
*/ */
virtual int correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag); 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(); virtual int get_time();
}; };
#ifdef SRS_PERF_QUEUE_FAST_VECTOR #ifdef SRS_PERF_QUEUE_FAST_VECTOR
/** /**
* to alloc and increase fixed space, * to alloc and increase fixed space,
* fast remove and insert for msgs sender. * fast remove and insert for msgs sender.
* @see https://github.com/ossrs/srs/issues/251 * @see https://github.com/ossrs/srs/issues/251
*/ */
class SrsFastVector class SrsFastVector
{ {
private: private:
@ -133,9 +129,9 @@ public:
#endif #endif
/** /**
* the message queue for the consumer(client), forwarder. * the message queue for the consumer(client), forwarder.
* we limit the size in seconds, drop old messages(the whole gop) if full. * we limit the size in seconds, drop old messages(the whole gop) if full.
*/ */
class SrsMessageQueue class SrsMessageQueue
{ {
private: private:
@ -153,24 +149,24 @@ public:
virtual ~SrsMessageQueue(); virtual ~SrsMessageQueue();
public: public:
/** /**
* get the size of queue. * get the size of queue.
*/ */
virtual int size(); virtual int size();
/** /**
* get the duration of queue. * get the duration of queue.
*/ */
virtual int duration(); virtual int duration();
/** /**
* set the queue size * set the queue size
* @param queue_size the queue size in seconds. * @param queue_size the queue size in seconds.
*/ */
virtual void set_queue_size(double queue_size); virtual void set_queue_size(double queue_size);
public: public:
/** /**
* enqueue the message, the timestamp always monotonically. * enqueue the message, the timestamp always monotonically.
* @param msg, the msg to enqueue, user never free it whatever the return code. * @param msg, the msg to enqueue, user never free it whatever the return code.
* @param is_overflow, whether overflow and shrinked. NULL to ignore. * @param is_overflow, whether overflow and shrinked. NULL to ignore.
*/ */
virtual int enqueue(SrsSharedPtrMessage* msg, bool* is_overflow = NULL); virtual int enqueue(SrsSharedPtrMessage* msg, bool* is_overflow = NULL);
/** /**
* get packets in consumer queue. * get packets in consumer queue.
@ -180,15 +176,15 @@ public:
*/ */
virtual int dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count); virtual int dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count);
/** /**
* dumps packets to consumer, use specified args. * dumps packets to consumer, use specified args.
* @remark the atc/tba/tbv/ag are same to SrsConsumer.enqueue(). * @remark the atc/tba/tbv/ag are same to SrsConsumer.enqueue().
*/ */
virtual int dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag); virtual int dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag);
private: private:
/** /**
* remove a gop from the front. * remove a gop from the front.
* if no iframe found, clear it. * if no iframe found, clear it.
*/ */
virtual void shrink(); virtual void shrink();
public: 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 class SrsConsumer : public ISrsWakable
{ {
private: private:
@ -242,24 +238,24 @@ public:
virtual ~SrsConsumer(); virtual ~SrsConsumer();
public: public:
/** /**
* set the size of queue. * set the size of queue.
*/ */
virtual void set_queue_size(double queue_size); 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(); virtual void update_source_id();
public: public:
/** /**
* get current client time, the last packet time. * get current client time, the last packet time.
*/ */
virtual int get_time(); virtual int get_time();
/** /**
* enqueue an shared ptr message. * enqueue an shared ptr message.
* @param shared_msg, directly ptr, copy it if need to save it. * @param shared_msg, directly ptr, copy it if need to save it.
* @param whether atc, donot use jitter correct if true. * @param whether atc, donot use jitter correct if true.
* @param ag the algorithm of time jitter. * @param ag the algorithm of time jitter.
*/ */
virtual int enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag); virtual int enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag);
/** /**
* get packets in consumer queue. * get packets in consumer queue.
@ -270,17 +266,17 @@ public:
virtual int dump_packets(SrsMessageArray* msgs, int& count); virtual int dump_packets(SrsMessageArray* msgs, int& count);
#ifdef SRS_PERF_QUEUE_COND_WAIT #ifdef SRS_PERF_QUEUE_COND_WAIT
/** /**
* wait for messages incomming, atleast nb_msgs and in duration. * wait for messages incomming, atleast nb_msgs and in duration.
* @param nb_msgs the messages count to wait. * @param nb_msgs the messages count to wait.
* @param duration the messgae duration to wait. * @param duration the messgae duration to wait.
*/ */
virtual void wait(int nb_msgs, int duration); virtual void wait(int nb_msgs, int duration);
#endif #endif
/** /**
* when client send the pause message. * when client send the pause message.
*/ */
virtual int on_play_client_pause(bool is_pause); virtual int on_play_client_pause(bool is_pause);
// ISrsWakable // ISrsWakable
public: public:
/** /**
* when the consumer(for player) got msg from recv thread, * when the consumer(for player) got msg from recv thread,
@ -291,39 +287,39 @@ public:
}; };
/** /**
* cache a gop of video/audio data, * cache a gop of video/audio data,
* delivery at the connect of flash player, * delivery at the connect of flash player,
* to enable it to fast startup. * to enable it to fast startup.
*/ */
class SrsGopCache class SrsGopCache
{ {
private: private:
/** /**
* if disabled the gop cache, * if disabled the gop cache,
* the client will wait for the next keyframe for h264, * the client will wait for the next keyframe for h264,
* and will be black-screen. * and will be black-screen.
*/ */
bool enable_gop_cache; 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; int cached_video_count;
/** /**
* when user disabled video when publishing, and gop cache enalbed, * when user disabled video when publishing, and gop cache enalbed,
* we will cache the audio/video for we already got video, but we never * 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, * know when to clear the gop cache, for there is no video in future,
* so we must guess whether user disabled the video. * so we must guess whether user disabled the video.
* when we got some audios after laster video, for instance, 600 audio packets, * when we got some audios after laster video, for instance, 600 audio packets,
* about 3s(26ms per packet) 115 audio packets, clear gop cache. * about 3s(26ms per packet) 115 audio packets, clear gop cache.
* *
* @remark, it is ok for performance, for when we clear the gop cache, * @remark, it is ok for performance, for when we clear the gop cache,
* gop cache is disabled for pure audio stream. * gop cache is disabled for pure audio stream.
* @see: https://github.com/ossrs/srs/issues/124 * @see: https://github.com/ossrs/srs/issues/124
*/ */
int audio_after_last_video_count; int audio_after_last_video_count;
/** /**
* cached gop. * cached gop.
*/ */
std::vector<SrsSharedPtrMessage*> gop_cache; std::vector<SrsSharedPtrMessage*> gop_cache;
public: public:
SrsGopCache(); SrsGopCache();
@ -334,47 +330,47 @@ public:
*/ */
virtual void dispose(); virtual void dispose();
/** /**
* to enable or disable the gop cache. * to enable or disable the gop cache.
*/ */
virtual void set(bool v); virtual void set(bool v);
virtual bool enabled(); virtual bool enabled();
/** /**
* only for h264 codec * only for h264 codec
* 1. cache the gop when got h264 video packet. * 1. cache the gop when got h264 video packet.
* 2. clear gop when got keyframe. * 2. clear gop when got keyframe.
* @param shared_msg, directly ptr, copy it if need to save it. * @param shared_msg, directly ptr, copy it if need to save it.
*/ */
virtual int cache(SrsSharedPtrMessage* shared_msg); virtual int cache(SrsSharedPtrMessage* shared_msg);
/** /**
* clear the gop cache. * clear the gop cache.
*/ */
virtual void clear(); 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); virtual int dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm);
/** /**
* used for atc to get the time of gop cache, * used for atc to get the time of gop cache,
* the atc will adjust the sequence header timestamp to gop cache. * the atc will adjust the sequence header timestamp to gop cache.
*/ */
virtual bool empty(); virtual bool empty();
/** /**
* get the start time of gop cache, in ms. * get the start time of gop cache, in ms.
* @return 0 if no packets. * @return 0 if no packets.
*/ */
virtual int64_t start_time(); virtual int64_t start_time();
/** /**
* whether current stream is pure audio, * whether current stream is pure audio,
* when no video in gop cache, the stream is pure audio right now. * when no video in gop cache, the stream is pure audio right now.
*/ */
virtual bool pure_audio(); virtual bool pure_audio();
}; };
/** /**
* the handler to handle the event of srs source. * the handler to handle the event of srs source.
* for example, the http flv streaming module handle the event and * for example, the http flv streaming module handle the event and
* mount http when rtmp start publishing. * mount http when rtmp start publishing.
*/ */
class ISrsSourceHandler class ISrsSourceHandler
{ {
public: public:
@ -382,12 +378,12 @@ public:
virtual ~ISrsSourceHandler(); virtual ~ISrsSourceHandler();
public: public:
/** /**
* when stream start publish, mount stream. * when stream start publish, mount stream.
*/ */
virtual int on_publish(SrsSource* s, SrsRequest* r) = 0; 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; virtual void on_unpublish(SrsSource* s, SrsRequest* r) = 0;
}; };
@ -467,7 +463,7 @@ public:
virtual int on_publish(); virtual int on_publish();
// When stop publish stream. // When stop publish stream.
virtual void on_unpublish(); virtual void on_unpublish();
// Internal callback. // Internal callback.
public: public:
// for the SrsForwarder to callback to request the sequence headers. // for the SrsForwarder to callback to request the sequence headers.
virtual int on_forwarder_start(SrsForwarder* forwarder); virtual int on_forwarder_start(SrsForwarder* forwarder);
@ -527,8 +523,8 @@ public:
}; };
/** /**
* live streaming source. * live streaming source.
*/ */
class SrsSource : public ISrsReloadHandler class SrsSource : public ISrsReloadHandler
{ {
friend class SrsOriginHub; friend class SrsOriginHub;
@ -536,17 +532,17 @@ private:
static std::map<std::string, SrsSource*> pool; static std::map<std::string, SrsSource*> pool;
public: public:
/** /**
* create source when fetch from cache failed. * create source when fetch from cache failed.
* @param r the client request. * @param r the client request.
* @param h the event handler for source. * @param h the event handler for source.
* @param pps the matched source, if success never be NULL. * @param pps the matched source, if success never be NULL.
*/ */
static int fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps); static int fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps);
private: private:
/** /**
* get the exists source, NULL when not exists. * get the exists source, NULL when not exists.
* update the request and return the exists source. * update the request and return the exists source.
*/ */
static SrsSource* fetch(SrsRequest* r); static SrsSource* fetch(SrsRequest* r);
public: public:
/** /**
@ -558,9 +554,9 @@ private:
static int do_cycle_all(); static int do_cycle_all();
public: public:
/** /**
* when system exit, destroy the sources, * when system exit, destroy the sources,
* for gmc to analysis mem leaks. * for gmc to analysis mem leaks.
*/ */
static void destroy(); static void destroy();
private: private:
// source id, // source id,
@ -607,8 +603,8 @@ private:
SrsMetaCache* meta; SrsMetaCache* meta;
private: private:
/** /**
* can publish, true when is not streaming * can publish, true when is not streaming
*/ */
bool _can_publish; bool _can_publish;
// last die time, when all consumers quit and no publisher, // last die time, when all consumers quit and no publisher,
// we will remove the source when source die. // we will remove the source when source die.
@ -621,23 +617,23 @@ public:
virtual int cycle(); virtual int cycle();
// remove source when expired. // remove source when expired.
virtual bool expired(); virtual bool expired();
// initialize, get and setter. // initialize, get and setter.
public: public:
/** /**
* initialize the hls with handlers. * initialize the hls with handlers.
*/ */
virtual int initialize(SrsRequest* r, ISrsSourceHandler* h); virtual int initialize(SrsRequest* r, ISrsSourceHandler* h);
// interface ISrsReloadHandler // interface ISrsReloadHandler
public: public:
virtual int on_reload_vhost_play(std::string vhost); virtual int on_reload_vhost_play(std::string vhost);
// for the tools callback // for the tools callback
public: public:
// source id changed. // source id changed.
virtual int on_source_id_changed(int id); virtual int on_source_id_changed(int id);
// get current source id. // get current source id.
virtual int source_id(); virtual int source_id();
virtual int pre_source_id(); virtual int pre_source_id();
// logic data methods // logic data methods
public: public:
virtual bool can_publish(bool is_edge); virtual bool can_publish(bool is_edge);
virtual int on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata); virtual int on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata);
@ -652,29 +648,26 @@ private:
public: public:
virtual int on_aggregate(SrsCommonMessage* msg); virtual int on_aggregate(SrsCommonMessage* msg);
/** /**
* publish stream event notify. * publish stream event notify.
* @param _req the request from client, the source will deep copy it, * @param _req the request from client, the source will deep copy it,
* for when reload the request of client maybe invalid. * for when reload the request of client maybe invalid.
*/ */
virtual int on_publish(); virtual int on_publish();
virtual void on_unpublish(); virtual void on_unpublish();
// consumer methods // consumer methods
public: public:
/** /**
* create consumer and dumps packets in cache. * create consumer and dumps packets in cache.
* @param consumer, output the create consumer. * @param consumer, output the create consumer.
* @param ds, whether dumps the sequence header. * @param ds, whether dumps the sequence header.
* @param dm, whether dumps the metadata. * @param dm, whether dumps the metadata.
* @param dg, whether dumps the gop cache. * @param dg, whether dumps the gop cache.
*/ */
virtual int create_consumer( virtual int create_consumer(SrsConnection* conn, SrsConsumer*& consumer, bool ds = true, bool dm = true, bool dg = true);
SrsConnection* conn, SrsConsumer*& consumer,
bool ds = true, bool dm = true, bool dg = true
);
virtual void on_consumer_destroy(SrsConsumer* consumer); virtual void on_consumer_destroy(SrsConsumer* consumer);
virtual void set_cache(bool enabled); virtual void set_cache(bool enabled);
virtual SrsRtmpJitterAlgorithm jitter(); virtual SrsRtmpJitterAlgorithm jitter();
// internal // internal
public: public:
// for edge, when publish edge stream, check the state // for edge, when publish edge stream, check the state
virtual int on_edge_start_publish(); virtual int on_edge_start_publish();

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_st.hpp> #include <srs_app_st.hpp>
@ -501,12 +501,12 @@ int SrsTcpClient::writev(const iovec *iov, int iov_size, ssize_t* nwrite)
bool srs_st_epoll_is_supported(void) bool srs_st_epoll_is_supported(void)
{ {
struct epoll_event ev; struct epoll_event ev;
ev.events = EPOLLIN; ev.events = EPOLLIN;
ev.data.ptr = NULL; ev.data.ptr = NULL;
/* Guaranteed to fail */ /* Guaranteed to fail */
epoll_ctl(-1, EPOLL_CTL_ADD, -1, &ev); epoll_ctl(-1, EPOLL_CTL_ADD, -1, &ev);
return (errno != ENOSYS); return (errno != ENOSYS);
} }
#endif #endif
@ -533,7 +533,7 @@ int srs_st_init()
return ret; return ret;
} }
srs_info("st_set_eventsys to %s", st_get_eventsys_name()); srs_info("st_set_eventsys to %s", st_get_eventsys_name());
if(st_init() != 0){ if(st_init() != 0){
ret = ERROR_ST_INITIALIZE; ret = ERROR_ST_INITIALIZE;
srs_error("st_init failed. ret=%d", ret); srs_error("st_init failed. ret=%d", ret);

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_ST_HPP #ifndef SRS_APP_ST_HPP
#define SRS_APP_ST_HPP #define SRS_APP_ST_HPP
/*
#include <srs_app_st.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <string> #include <string>

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_statistic.hpp> #include <srs_app_statistic.hpp>
@ -308,15 +308,13 @@ SrsStatisticClient* SrsStatistic::find_client(int cid)
return NULL; return NULL;
} }
int SrsStatistic::on_video_info(SrsRequest* req, int SrsStatistic::on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, int width, int height)
SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, {
int width, int height
) {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsStatisticVhost* vhost = create_vhost(req); SrsStatisticVhost* vhost = create_vhost(req);
SrsStatisticStream* stream = create_stream(vhost, req); SrsStatisticStream* stream = create_stream(vhost, req);
stream->has_video = true; stream->has_video = true;
stream->vcodec = vcodec; stream->vcodec = vcodec;
stream->avc_profile = avc_profile; stream->avc_profile = avc_profile;
@ -328,15 +326,13 @@ int SrsStatistic::on_video_info(SrsRequest* req,
return ret; return ret;
} }
int SrsStatistic::on_audio_info(SrsRequest* req, int SrsStatistic::on_audio_info(SrsRequest* req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object)
SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, {
SrsAacObjectType aac_object
) {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsStatisticVhost* vhost = create_vhost(req); SrsStatisticVhost* vhost = create_vhost(req);
SrsStatisticStream* stream = create_stream(vhost, req); SrsStatisticStream* stream = create_stream(vhost, req);
stream->has_audio = true; stream->has_audio = true;
stream->acodec = acodec; stream->acodec = acodec;
stream->asample_rate = asample_rate; stream->asample_rate = asample_rate;
@ -350,7 +346,7 @@ void SrsStatistic::on_stream_publish(SrsRequest* req, int cid)
{ {
SrsStatisticVhost* vhost = create_vhost(req); SrsStatisticVhost* vhost = create_vhost(req);
SrsStatisticStream* stream = create_stream(vhost, req); SrsStatisticStream* stream = create_stream(vhost, req);
stream->publish(cid); stream->publish(cid);
} }
@ -383,7 +379,7 @@ int SrsStatistic::on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtm
SrsStatisticVhost* vhost = create_vhost(req); SrsStatisticVhost* vhost = create_vhost(req);
SrsStatisticStream* stream = create_stream(vhost, req); SrsStatisticStream* stream = create_stream(vhost, req);
// create client if not exists // create client if not exists
SrsStatisticClient* client = NULL; SrsStatisticClient* client = NULL;
if (clients.find(id) == clients.end()) { if (clients.find(id) == clients.end()) {
@ -401,7 +397,7 @@ int SrsStatistic::on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtm
client->type = type; client->type = type;
stream->nb_clients++; stream->nb_clients++;
vhost->nb_clients++; vhost->nb_clients++;
return ret; return ret;
} }
@ -411,7 +407,7 @@ void SrsStatistic::on_disconnect(int id)
if ((it = clients.find(id)) == clients.end()) { if ((it = clients.find(id)) == clients.end()) {
return; return;
} }
SrsStatisticClient* client = it->second; SrsStatisticClient* client = it->second;
SrsStatisticStream* stream = client->stream; SrsStatisticStream* stream = client->stream;
SrsStatisticVhost* vhost = stream->vhost; SrsStatisticVhost* vhost = stream->vhost;
@ -474,7 +470,7 @@ int64_t SrsStatistic::server_id()
int SrsStatistic::dumps_vhosts(SrsJsonArray* arr) int SrsStatistic::dumps_vhosts(SrsJsonArray* arr)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
std::map<int64_t, SrsStatisticVhost*>::iterator it; std::map<int64_t, SrsStatisticVhost*>::iterator it;
for (it = vhosts.begin(); it != vhosts.end(); it++) { for (it = vhosts.begin(); it != vhosts.end(); it++) {
SrsStatisticVhost* vhost = it->second; SrsStatisticVhost* vhost = it->second;
@ -486,7 +482,7 @@ int SrsStatistic::dumps_vhosts(SrsJsonArray* arr)
return ret; return ret;
} }
} }
return ret; return ret;
} }
@ -500,7 +496,7 @@ int SrsStatistic::dumps_streams(SrsJsonArray* arr)
SrsJsonObject* obj = SrsJsonAny::object(); SrsJsonObject* obj = SrsJsonAny::object();
arr->append(obj); arr->append(obj);
if ((ret = stream->dumps(obj)) != ERROR_SUCCESS) { if ((ret = stream->dumps(obj)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -544,7 +540,7 @@ SrsStatisticVhost* SrsStatistic::create_vhost(SrsRequest* req)
vhosts[vhost->id] = vhost; vhosts[vhost->id] = vhost;
return vhost; return vhost;
} }
vhost = rvhosts[req->vhost]; vhost = rvhosts[req->vhost];
return vhost; return vhost;

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_STATISTIC_HPP #ifndef SRS_APP_STATISTIC_HPP
#define SRS_APP_STATISTIC_HPP #define SRS_APP_STATISTIC_HPP
/*
#include <srs_app_statistic.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <map> #include <map>
@ -52,8 +48,8 @@ public:
int nb_clients; int nb_clients;
public: public:
/** /**
* vhost total kbps. * vhost total kbps.
*/ */
SrsKbps* kbps; SrsKbps* kbps;
public: public:
SrsStatisticVhost(); SrsStatisticVhost();
@ -75,8 +71,8 @@ public:
int nb_clients; int nb_clients;
public: public:
/** /**
* stream total kbps. * stream total kbps.
*/ */
SrsKbps* kbps; SrsKbps* kbps;
public: public:
bool has_video; bool has_video;
@ -94,11 +90,11 @@ public:
SrsAudioSampleRate asample_rate; SrsAudioSampleRate asample_rate;
SrsAudioChannels asound_type; SrsAudioChannels asound_type;
/** /**
* audio specified * audio specified
* audioObjectType, in 1.6.2.1 AudioSpecificConfig, page 33, * audioObjectType, in 1.6.2.1 AudioSpecificConfig, page 33,
* 1.5.1.1 Audio object type definition, page 23, * 1.5.1.1 Audio object type definition, page 23,
* in ISO_IEC_14496-3-AAC-2001.pdf. * in ISO_IEC_14496-3-AAC-2001.pdf.
*/ */
SrsAacObjectType aac_object; SrsAacObjectType aac_object;
public: public:
SrsStatisticStream(); SrsStatisticStream();
@ -107,12 +103,12 @@ public:
virtual int dumps(SrsJsonObject* obj); virtual int dumps(SrsJsonObject* obj);
public: public:
/** /**
* publish the stream. * publish the stream.
*/ */
virtual void publish(int cid); virtual void publish(int cid);
/** /**
* close the stream. * close the stream.
*/ */
virtual void close(); virtual void close();
}; };
@ -167,19 +163,13 @@ public:
virtual SrsStatisticClient* find_client(int cid); virtual SrsStatisticClient* find_client(int cid);
public: public:
/** /**
* when got video info for stream. * when got video info for stream.
*/ */
virtual int on_video_info(SrsRequest* req, virtual int on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, int width, int height);
SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level,
int width, int height
);
/** /**
* when got audio info for stream. * when got audio info for stream.
*/ */
virtual int on_audio_info(SrsRequest* req, virtual int on_audio_info(SrsRequest* req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object);
SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type,
SrsAacObjectType aac_object
);
/** /**
* when publish stream. * when publish stream.
* @param req the request object of publish connection. * @param req the request object of publish connection.
@ -187,8 +177,8 @@ public:
*/ */
virtual void on_stream_publish(SrsRequest* req, int cid); virtual void on_stream_publish(SrsRequest* req, int cid);
/** /**
* when close stream. * when close stream.
*/ */
virtual void on_stream_close(SrsRequest* req); virtual void on_stream_close(SrsRequest* req);
public: public:
/** /**
@ -207,29 +197,29 @@ public:
*/ */
virtual void on_disconnect(int id); virtual void on_disconnect(int id);
/** /**
* sample the kbps, add delta bytes of conn. * sample the kbps, add delta bytes of conn.
* use kbps_sample() to get all result of kbps stat. * use kbps_sample() to get all result of kbps stat.
*/ */
// TODO: FIXME: the add delta must use IKbpsDelta interface instead. // TODO: FIXME: the add delta must use IKbpsDelta interface instead.
virtual void kbps_add_delta(SrsConnection* conn); virtual void kbps_add_delta(SrsConnection* conn);
/** /**
* calc the result for all kbps. * calc the result for all kbps.
* @return the server kbps. * @return the server kbps.
*/ */
virtual SrsKbps* kbps_sample(); virtual SrsKbps* kbps_sample();
public: public:
/** /**
* get the server id, used to identify the server. * get the server id, used to identify the server.
* for example, when restart, the server id must changed. * for example, when restart, the server id must changed.
*/ */
virtual int64_t server_id(); virtual int64_t server_id();
/** /**
* dumps the vhosts to amf0 array. * dumps the vhosts to amf0 array.
*/ */
virtual int dumps_vhosts(SrsJsonArray* arr); virtual int dumps_vhosts(SrsJsonArray* arr);
/** /**
* dumps the streams to amf0 array. * dumps the streams to amf0 array.
*/ */
virtual int dumps_streams(SrsJsonArray* arr); virtual int dumps_streams(SrsJsonArray* arr);
/** /**
* dumps the clients to amf0 array * dumps the clients to amf0 array

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_thread.hpp> #include <srs_app_thread.hpp>

View file

@ -1,32 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_THREAD_HPP #ifndef SRS_APP_THREAD_HPP
#define SRS_APP_THREAD_HPP #define SRS_APP_THREAD_HPP
/*
#include <srs_app_thread.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <srs_app_st.hpp> #include <srs_app_st.hpp>

View file

@ -1,25 +1,25 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_app_utility.hpp> #include <srs_app_utility.hpp>
@ -246,7 +246,7 @@ int srs_kill_forced(int& pid)
return ret; return ret;
} }
// then, try kill by SIGKILL. // then, try kill by SIGKILL.
if (kill(pid, SIGKILL) < 0) { if (kill(pid, SIGKILL) < 0) {
return ERROR_SYSTEM_KILL; 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 // @see: read_stat_cpu() from https://github.com/sysstat/sysstat/blob/master/rd_stats.c#L88
// @remark, ignore the filed 10 cpu_guest_nice // @remark, ignore the filed 10 cpu_guest_nice
sscanf(buf + 5, "%llu %llu %llu %llu %llu %llu %llu %llu %llu\n", sscanf(buf + 5, "%llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
&r.user, &r.user,
&r.nice, &r.nice,
&r.sys, &r.sys,
&r.idle, &r.idle,
&r.iowait, &r.iowait,
&r.irq, &r.irq,
&r.softirq, &r.softirq,
&r.steal, &r.steal,
&r.guest); &r.guest);
break; break;
} }
@ -420,7 +420,7 @@ bool get_proc_system_stat(SrsProcSystemStat& r)
// TODO: FIXME: impelments it. // TODO: FIXME: impelments it.
// Fuck all of you who use osx for a long time and never patch the osx features for srs. // Fuck all of you who use osx for a long time and never patch the osx features for srs.
#endif #endif
r.ok = true; r.ok = true;
return true; return true;
@ -436,23 +436,23 @@ bool get_proc_self_stat(SrsProcSelfStat& r)
} }
fscanf(f, "%d %32s %c %d %d %d %d " fscanf(f, "%d %32s %c %d %d %d %d "
"%d %u %lu %lu %lu %lu " "%d %u %lu %lu %lu %lu "
"%lu %lu %ld %ld %ld %ld " "%lu %lu %ld %ld %ld %ld "
"%ld %ld %llu %lu %ld " "%ld %ld %llu %lu %ld "
"%lu %lu %lu %lu %lu " "%lu %lu %lu %lu %lu "
"%lu %lu %lu %lu %lu " "%lu %lu %lu %lu %lu "
"%lu %lu %lu %d %d " "%lu %lu %lu %d %d "
"%u %u %llu " "%u %u %llu "
"%lu %ld", "%lu %ld",
&r.pid, r.comm, &r.state, &r.ppid, &r.pgrp, &r.session, &r.tty_nr, &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.tpgid, &r.flags, &r.minflt, &r.cminflt, &r.majflt, &r.cmajflt,
&r.utime, &r.stime, &r.cutime, &r.cstime, &r.priority, &r.nice, &r.utime, &r.stime, &r.cutime, &r.cstime, &r.priority, &r.nice,
&r.num_threads, &r.itrealvalue, &r.starttime, &r.vsize, &r.rss, &r.num_threads, &r.itrealvalue, &r.starttime, &r.vsize, &r.rss,
&r.rsslim, &r.startcode, &r.endcode, &r.startstack, &r.kstkesp, &r.rsslim, &r.startcode, &r.endcode, &r.startstack, &r.kstkesp,
&r.kstkeip, &r.signal, &r.blocked, &r.sigignore, &r.sigcatch, &r.kstkeip, &r.signal, &r.blocked, &r.sigignore, &r.sigcatch,
&r.wchan, &r.nswap, &r.cnswap, &r.exit_signal, &r.processor, &r.wchan, &r.nswap, &r.cnswap, &r.exit_signal, &r.processor,
&r.rt_priority, &r.policy, &r.delayacct_blkio_ticks, &r.rt_priority, &r.policy, &r.delayacct_blkio_ticks,
&r.guest_time, &r.cguest_time); &r.guest_time, &r.cguest_time);
fclose(f); fclose(f);
#else #else
@ -620,22 +620,22 @@ bool srs_get_disk_diskstats_stat(SrsDiskStat& r)
unsigned int aveq = 0; unsigned int aveq = 0;
memset(name, 0, sizeof(name)); memset(name, 0, sizeof(name));
sscanf(buf, "%4d %4d %31s %u %u %llu %u %u %u %llu %u %u %u %u", sscanf(buf, "%4d %4d %31s %u %u %llu %u %u %u %llu %u %u %u %u",
&major, &major,
&minor, &minor,
name, name,
&rd_ios, &rd_ios,
&rd_merges, &rd_merges,
&rd_sectors, &rd_sectors,
&rd_ticks, &rd_ticks,
&wr_ios, &wr_ios,
&wr_merges, &wr_merges,
&wr_sectors, &wr_sectors,
&wr_ticks, &wr_ticks,
&nb_current, &nb_current,
&ticks, &ticks,
&aveq); &aveq);
for (int i = 0; i < (int)conf->args.size(); i++) { for (int i = 0; i < (int)conf->args.size(); i++) {
string name_ok = conf->args.at(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 if (r.cpu.ok && r.cpu.total_delta > 0
&& cpuinfo->ok && cpuinfo->nb_processors > 0 && cpuinfo->ok && cpuinfo->nb_processors > 0
&& o.ticks < r.ticks && o.ticks < r.ticks
) { ) {
// @see: write_ext_stat() from https://github.com/sysstat/sysstat/blob/master/iostat.c#L979 // @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. // 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; 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); fscanf(f, "%lf %lf\n", &r.os_uptime, &r.os_ilde_time);
fclose(f); 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 // @see: read_loadavg() from https://github.com/sysstat/sysstat/blob/master/rd_stats.c#L402
// @remark, we use our algorithm, not sysstat. // @remark, we use our algorithm, not sysstat.
fscanf(f, "%lf %lf %lf\n", fscanf(f, "%lf %lf %lf\n",
&r.load_one_minutes, &r.load_one_minutes,
&r.load_five_minutes, &r.load_five_minutes,
&r.load_fifteen_minutes); &r.load_fifteen_minutes);
fclose(f); fclose(f);
} }
#else #else
@ -977,21 +977,21 @@ void srs_update_network_devices()
static char buf[1024]; static char buf[1024];
fgets(buf, sizeof(buf), f); fgets(buf, sizeof(buf), f);
fgets(buf, sizeof(buf), f); fgets(buf, sizeof(buf), f);
for (int i = 0; i < MAX_NETWORK_DEVICES_COUNT; i++) { for (int i = 0; i < MAX_NETWORK_DEVICES_COUNT; i++) {
if (!fgets(buf, sizeof(buf), f)) { if (!fgets(buf, sizeof(buf), f)) {
break; break;
} }
SrsNetworkDevices& r = _srs_system_network_devices[i]; SrsNetworkDevices& r = _srs_system_network_devices[i];
// @see: read_net_dev() from https://github.com/sysstat/sysstat/blob/master/rd_stats.c#L786 // @see: read_net_dev() from https://github.com/sysstat/sysstat/blob/master/rd_stats.c#L786
// @remark, we use our algorithm, not sysstat. // @remark, we use our algorithm, not sysstat.
char fname[7]; char fname[7];
sscanf(buf, "%6[^:]:%llu %lu %lu %lu %lu %lu %lu %lu %llu %lu %lu %lu %lu %lu %lu %lu\n", 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, 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); &r.sbytes, &r.spackets, &r.serrs, &r.sdrop, &r.sfifo, &r.scolls, &r.scarrier, &r.scompressed);
sscanf(fname, "%s", r.name); sscanf(fname, "%s", r.name);
_nb_srs_system_network_devices = i + 1; _nb_srs_system_network_devices = i + 1;
srs_info("scan network device ifname=%s, total=%d", r.name, _nb_srs_system_network_devices); 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.sample_time = srs_get_system_time_ms();
r.ok = true; r.ok = true;
} }
fclose(f); fclose(f);
} }
#else #else
@ -1016,7 +1016,7 @@ static std::map<std::string, bool> _srs_device_ifs;
bool srs_net_device_is_internet(string ifname) bool srs_net_device_is_internet(string ifname)
{ {
srs_info("check ifname=%s", ifname.c_str()); srs_info("check ifname=%s", ifname.c_str());
if (_srs_device_ifs.find(ifname) == _srs_device_ifs.end()) { if (_srs_device_ifs.find(ifname) == _srs_device_ifs.end()) {
return false; return false;
} }
@ -1079,14 +1079,14 @@ enum {
SYS_TCP_LAST_ACK, // 0x09 SYS_TCP_LAST_ACK, // 0x09
SYS_TCP_LISTEN, // 0x0A SYS_TCP_LISTEN, // 0x0A
SYS_TCP_CLOSING, // 0x0B /* Now a valid state */ SYS_TCP_CLOSING, // 0x0B /* Now a valid state */
SYS_TCP_MAX_STATES // 0x0C /* Leave at the end! */ SYS_TCP_MAX_STATES // 0x0C /* Leave at the end! */
}; };
void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps) void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps)
{ {
SrsNetworkRtmpServer& r = _srs_network_rtmp_server; SrsNetworkRtmpServer& r = _srs_network_rtmp_server;
int nb_socks = 0; int nb_socks = 0;
int nb_tcp4_hashed = 0; int nb_tcp4_hashed = 0;
int nb_tcp_orphans = 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) { if (strncmp(buf, "sockets: used ", 14) == 0) {
sscanf(buf + 14, "%d\n", &nb_socks); sscanf(buf + 14, "%d\n", &nb_socks);
} else if (strncmp(buf, "TCP: ", 5) == 0) { } else if (strncmp(buf, "TCP: ", 5) == 0) {
sscanf(buf + 5, "%*s %d %*s %d %*s %d %*s %d %*s %d\n", sscanf(buf + 5, "%*s %d %*s %d %*s %d %*s %d %*s %d\n",
&nb_tcp4_hashed, &nb_tcp4_hashed,
&nb_tcp_orphans, &nb_tcp_orphans,
&nb_tcp_tws, &nb_tcp_tws,
&nb_tcp_total, &nb_tcp_total,
&nb_tcp_mem); &nb_tcp_mem);
} else if (strncmp(buf, "UDP: ", 5) == 0) { } else if (strncmp(buf, "UDP: ", 5) == 0) {
sscanf(buf + 5, "%*s %d\n", &nb_udp4); sscanf(buf + 5, "%*s %d\n", &nb_udp4);
} }
} }
fclose(f); fclose(f);
} }
#else #else
@ -1166,7 +1166,7 @@ void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps)
} }
} }
} }
fclose(f); fclose(f);
} }
#else #else
@ -1229,7 +1229,7 @@ void retrieve_local_ipv4_ips()
p = p->ifa_next; p = p->ifa_next;
// retrieve ipv4 addr // retrieve ipv4 addr
// ignore the tun0 network device, // ignore the tun0 network device,
// which addr is NULL. // which addr is NULL.
// @see: https://github.com/ossrs/srs/issues/141 // @see: https://github.com/ossrs/srs/issues/141
if (addr && addr->sa_family == AF_INET) { if (addr && addr->sa_family == AF_INET) {
@ -1262,7 +1262,7 @@ void retrieve_local_ipv4_ips()
} }
srs_trace(ss0.str().c_str()); srs_trace(ss0.str().c_str());
srs_trace(ss1.str().c_str()); srs_trace(ss1.str().c_str());
freeifaddrs(ifap); freeifaddrs(ifap);
} }
@ -1271,7 +1271,7 @@ vector<string>& srs_get_local_ipv4_ips()
if (_srs_system_ipv4_ips.empty()) { if (_srs_system_ipv4_ips.empty()) {
retrieve_local_ipv4_ips(); retrieve_local_ipv4_ips();
} }
return _srs_system_ipv4_ips; return _srs_system_ipv4_ips;
} }
@ -1338,7 +1338,7 @@ string srs_get_public_internet_address()
string srs_get_local_ip(int fd) string srs_get_local_ip(int fd)
{ {
std::string ip; std::string ip;
// discovery client information // discovery client information
sockaddr_in addr; sockaddr_in addr;
socklen_t addrlen = sizeof(addr); socklen_t addrlen = sizeof(addr);
@ -1346,19 +1346,19 @@ string srs_get_local_ip(int fd)
return ip; return ip;
} }
srs_verbose("get local ip success."); srs_verbose("get local ip success.");
// ip v4 or v6 // ip v4 or v6
char buf[INET6_ADDRSTRLEN]; char buf[INET6_ADDRSTRLEN];
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
if ((inet_ntop(addr.sin_family, &addr.sin_addr, buf, sizeof(buf))) == NULL) { if ((inet_ntop(addr.sin_family, &addr.sin_addr, buf, sizeof(buf))) == NULL) {
return ip; return ip;
} }
ip = buf; ip = buf;
srs_verbose("get local ip of client ip=%s, fd=%d", buf, fd); srs_verbose("get local ip of client ip=%s, fd=%d", buf, fd);
return ip; return ip;
} }
@ -1373,9 +1373,9 @@ int srs_get_local_port(int fd)
srs_verbose("get local ip success."); srs_verbose("get local ip success.");
int port = ntohs(addr.sin_port); int port = ntohs(addr.sin_port);
srs_verbose("get local ip of client port=%s, fd=%d", port, fd); srs_verbose("get local ip of client port=%s, fd=%d", port, fd);
return port; return port;
} }
@ -1390,7 +1390,7 @@ string srs_get_peer_ip(int fd)
return ip; return ip;
} }
srs_verbose("get peer name success."); srs_verbose("get peer name success.");
// ip v4 or v6 // ip v4 or v6
char buf[INET6_ADDRSTRLEN]; char buf[INET6_ADDRSTRLEN];
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
@ -1483,8 +1483,8 @@ void srs_api_dump_summaries(SrsJsonObject* obj)
} }
// all data is ok? // all data is ok?
bool ok = (r->ok && u->ok && s->ok && c->ok bool ok = (r->ok && u->ok && s->ok && c->ok
&& d->ok && m->ok && p->ok && nrs->ok); && d->ok && m->ok && p->ok && nrs->ok);
SrsJsonObject* data = SrsJsonAny::object(); SrsJsonObject* data = SrsJsonAny::object();
obj->set("data", data); obj->set("data", data);

View file

@ -1,33 +1,29 @@
/* /**
The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_APP_UTILITY_HPP #ifndef SRS_APP_UTILITY_HPP
#define SRS_APP_UTILITY_HPP #define SRS_APP_UTILITY_HPP
/*
#include <srs_app_utility.hpp>
*/
#include <srs_core.hpp> #include <srs_core.hpp>
#include <vector> #include <vector>
@ -48,32 +44,32 @@ class SrsJsonObject;
extern int srs_socket_connect(std::string server, int port, int64_t tm, st_netfd_t* pstfd); 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. * convert level in string to log level in int.
* @return the log level defined in SrsLogLevel. * @return the log level defined in SrsLogLevel.
*/ */
extern int srs_get_log_level(std::string level); extern int srs_get_log_level(std::string level);
/** /**
* build the path according to vhost/app/stream, where replace variables: * build the path according to vhost/app/stream, where replace variables:
* [vhost], the vhost of stream. * [vhost], the vhost of stream.
* [app], the app of stream. * [app], the app of stream.
* [stream], the stream name of stream. * [stream], the stream name of stream.
* @return the replaced path. * @return the replaced path.
*/ */
extern std::string srs_path_build_stream(std::string template_path, std::string vhost, std::string app, std::string stream); 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: * build the path according to timestamp, where replace variables:
* [2006], replace this const to current year. * [2006], replace this const to current year.
* [01], replace this const to current month. * [01], replace this const to current month.
* [02], replace this const to current date. * [02], replace this const to current date.
* [15], replace this const to current hour. * [15], replace this const to current hour.
* [04], repleace this const to current minute. * [04], repleace this const to current minute.
* [05], repleace this const to current second. * [05], repleace this const to current second.
* [999], repleace this const to current millisecond. * [999], repleace this const to current millisecond.
* [timestamp],replace this const to current UNIX timestamp in ms. * [timestamp],replace this const to current UNIX timestamp in ms.
* @return the replaced path. * @return the replaced path.
*/ */
extern std::string srs_path_build_timestamp(std::string template_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%. // the percent of usage. 0.153 is 15.3%.
float percent; float percent;
// data of /proc/[pid]/stat // data of /proc/[pid]/stat
public: public:
// pid %d The process ID. // pid %d The process ID.
int pid; int pid;
@ -186,7 +182,7 @@ public:
long num_threads; long num_threads;
// itrealvalue %ld // itrealvalue %ld
// The time in jiffies before the next SIGALRM is sent to the process due to an interval timer. Since // 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; long itrealvalue;
// starttime %llu (was %lu before Linux 2.6) // starttime %llu (was %lu before Linux 2.6)
// The time in jiffies the process started after system boot. // The time in jiffies the process started after system boot.
@ -265,34 +261,34 @@ public:
// to stat the cpu time. // to stat the cpu time.
// @see: man 5 proc, /proc/stat // @see: man 5 proc, /proc/stat
/** /**
* about the cpu time, @see: http://stackoverflow.com/questions/16011677/calculating-cpu-usage-using-proc-files * 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: * for example, for ossrs.net, a single cpu machine:
* [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat * [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat
* 5275153.01 4699624.99 * 5275153.01 4699624.99
* cpu 43506750 973 8545744 466133337 4149365 190852 804666 0 0 * cpu 43506750 973 8545744 466133337 4149365 190852 804666 0 0
* where the uptime is 5275153.01s * 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" * 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 * that is, USER_HZ=1/100 seconds
* cpu total = 43506750+973+8545744+466133337+4149365+190852+804666+0+0 (USER_HZ) * cpu total = 43506750+973+8545744+466133337+4149365+190852+804666+0+0 (USER_HZ)
* = 523331687 (USER_HZ) * = 523331687 (USER_HZ)
* = 523331687 * 1/100 (seconds) * = 523331687 * 1/100 (seconds)
* = 5233316.87 seconds * = 5233316.87 seconds
* the cpu total seconds almost the uptime, the delta is more precise. * the cpu total seconds almost the uptime, the delta is more precise.
* *
* we run the command about 26minutes: * we run the command about 26minutes:
* [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat * [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat
* 5276739.83 4701090.76 * 5276739.83 4701090.76
* cpu 43514105 973 8548948 466278556 4150480 190899 804937 0 0 * cpu 43514105 973 8548948 466278556 4150480 190899 804937 0 0
* where the uptime is 5276739.83s * where the uptime is 5276739.83s
* cpu total = 43514105+973+8548948+466278556+4150480+190899+804937+0+0 (USER_HZ) * cpu total = 43514105+973+8548948+466278556+4150480+190899+804937+0+0 (USER_HZ)
* = 523488898 (USER_HZ) * = 523488898 (USER_HZ)
* = 523488898 * 1/100 (seconds) * = 523488898 * 1/100 (seconds)
* = 5234888.98 seconds * = 5234888.98 seconds
* where: * where:
* uptime delta = 1586.82s * uptime delta = 1586.82s
* cpu total delta = 1572.11s * cpu total delta = 1572.11s
* the deviation is more smaller. * the deviation is more smaller.
*/ */
class SrsProcSystemStat class SrsProcSystemStat
{ {
public: public:
@ -310,26 +306,26 @@ public:
// previous cpu total = this->total() - total_delta // previous cpu total = this->total() - total_delta
int64_t total_delta; int64_t total_delta;
// data of /proc/stat // data of /proc/stat
public: 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 // (1/100ths of a second on most architectures, use
// sysconf(_SC_CLK_TCK) to obtain the right value) // 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; unsigned long long user;
// user mode with low priority (nice), // user mode with low priority (nice),
unsigned long long nice; unsigned long long nice;
// system mode, // system mode,
unsigned long long sys; unsigned long long sys;
// and the idle task, respectively. // and the idle task, respectively.
unsigned long long idle; unsigned long long idle;
// In Linux 2.6 this line includes three additional columns: // In Linux 2.6 this line includes three additional columns:
// //
// iowait - time waiting for I/O to complete (since 2.5.41); // iowait - time waiting for I/O to complete (since 2.5.41);
unsigned long long iowait; 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; unsigned long long irq;
// softirq - time servicing softirqs (since 2.6.0-test4). // softirq - time servicing softirqs (since 2.6.0-test4).
unsigned long long softirq; unsigned long long softirq;
@ -339,11 +335,11 @@ public:
// ating systems when running in a virtualized environment // ating systems when running in a virtualized environment
unsigned long long steal; 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 // guest, which is the time spent running a virtual CPU for guest
// operating systems under the control of the Linux kernel. // operating systems under the control of the Linux kernel.
unsigned long long guest; unsigned long long guest;
public: public:
SrsProcSystemStat(); SrsProcSystemStat();
@ -399,63 +395,63 @@ public:
// @see: http://tester-higkoo.googlecode.com/svn-history/r14/trunk/Tools/iostat/iostat.c // @see: http://tester-higkoo.googlecode.com/svn-history/r14/trunk/Tools/iostat/iostat.c
// @see: cat /proc/diskstats // @see: cat /proc/diskstats
// //
// Number of issued reads. // Number of issued reads.
// This is the total number of reads completed successfully. // This is the total number of reads completed successfully.
// Read I/O operations // Read I/O operations
unsigned int rd_ios; unsigned int rd_ios;
// Number of reads merged // Number of reads merged
// Reads merged // Reads merged
unsigned int rd_merges; unsigned int rd_merges;
// Number of sectors read. // Number of sectors read.
// This is the total number of sectors read successfully. // This is the total number of sectors read successfully.
// Sectors read // Sectors read
unsigned long long rd_sectors; unsigned long long rd_sectors;
// Number of milliseconds spent reading. // Number of milliseconds spent reading.
// This is the total number of milliseconds spent by all reads // This is the total number of milliseconds spent by all reads
// (as measured from make_request() to end_that_request_last()). // (as measured from make_request() to end_that_request_last()).
// Time in queue + service for read // Time in queue + service for read
unsigned int rd_ticks; unsigned int rd_ticks;
// //
// Number of writes completed. // Number of writes completed.
// This is the total number of writes completed successfully // This is the total number of writes completed successfully
// Write I/O operations // Write I/O operations
unsigned int wr_ios; unsigned int wr_ios;
// Number of writes merged Reads and writes which are adjacent // Number of writes merged Reads and writes which are adjacent
// to each other may be merged for efficiency. Thus two 4K // to each other may be merged for efficiency. Thus two 4K
// reads may become one 8K read before it is ultimately // reads may become one 8K read before it is ultimately
// handed to the disk, and so it will be counted (and queued) // 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. // as only one I/O. This field lets you know how often this was done.
// Writes merged // Writes merged
unsigned int wr_merges; unsigned int wr_merges;
// Number of sectors written. // Number of sectors written.
// This is the total number of sectors written successfully. // This is the total number of sectors written successfully.
// Sectors written // Sectors written
unsigned long long wr_sectors; unsigned long long wr_sectors;
// Number of milliseconds spent writing . // Number of milliseconds spent writing .
// This is the total number of milliseconds spent by all writes // This is the total number of milliseconds spent by all writes
// (as measured from make_request() to end_that_request_last()). // (as measured from make_request() to end_that_request_last()).
// Time in queue + service for write // Time in queue + service for write
unsigned int wr_ticks; unsigned int wr_ticks;
// //
// Number of I/Os currently in progress. // Number of I/Os currently in progress.
// The only field that should go to zero. // The only field that should go to zero.
// Incremented as requests are given to appropriate request_queue_t // Incremented as requests are given to appropriate request_queue_t
// and decremented as they finish. // and decremented as they finish.
unsigned int nb_current; 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. // This field is increased so long as field 9 is nonzero.
// Time of requests in queue // Time of requests in queue
unsigned int ticks; unsigned int ticks;
// Number of milliseconds spent doing I/Os. // Number of milliseconds spent doing I/Os.
// This field is incremented at each I/O start, I/O completion, // 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 // I/O merge, or read of these stats by the number of I/Os in
// progress (field 9) times the number of milliseconds spent // progress (field 9) times the number of milliseconds spent
// doing I/O since the last update of this field. This can // doing I/O since the last update of this field. This can
// provide an easy measure of both I/O completion time and // provide an easy measure of both I/O completion time and
// the backlog that may be accumulating. // the backlog that may be accumulating.
// Average queue length // Average queue length
unsigned int aveq; unsigned int aveq;
public: public:
SrsDiskStat(); SrsDiskStat();
}; };
@ -466,7 +462,7 @@ extern SrsDiskStat* srs_get_disk_stat();
extern void srs_update_disk_stat(); extern void srs_update_disk_stat();
// stat system memory info // stat system memory info
// @see: cat /proc/meminfo // @see: cat /proc/meminfo
class SrsMemInfo class SrsMemInfo
{ {
public: public:
@ -478,7 +474,7 @@ public:
float percent_ram; float percent_ram;
float percent_swap; float percent_swap;
// data of /proc/meminfo // data of /proc/meminfo
public: public:
// MemActive = MemTotal - MemFree // MemActive = MemTotal - MemFree
uint64_t MemActive; uint64_t MemActive;
@ -507,7 +503,7 @@ extern SrsMemInfo* srs_get_meminfo();
extern void srs_update_meminfo(); extern void srs_update_meminfo();
// system cpu hardware info. // system cpu hardware info.
// @see: cat /proc/cpuinfo // @see: cat /proc/cpuinfo
// @remark, we use sysconf(_SC_NPROCESSORS_CONF) to get the cpu count. // @remark, we use sysconf(_SC_NPROCESSORS_CONF) to get the cpu count.
class SrsCpuInfo class SrsCpuInfo
{ {
@ -515,7 +511,7 @@ public:
// whether the data is ok. // whether the data is ok.
bool ok; bool ok;
// data of /proc/cpuinfo // data of /proc/cpuinfo
public: public:
// The number of processors configured. // The number of processors configured.
int nb_processors; int nb_processors;
@ -639,14 +635,14 @@ public:
int nb_conn_sys_et; // established int nb_conn_sys_et; // established
int nb_conn_sys_tw; // time wait int nb_conn_sys_tw; // time wait
int nb_conn_sys_udp; // udp int nb_conn_sys_udp; // udp
// retrieve from srs interface // retrieve from srs interface
int nb_conn_srs; int nb_conn_srs;
public: public:
SrsNetworkRtmpServer(); SrsNetworkRtmpServer();
}; };
// get network devices info, use cache to avoid performance problem. // get network devices info, use cache to avoid performance problem.
extern SrsNetworkRtmpServer* srs_get_network_rtmp_server(); extern SrsNetworkRtmpServer* srs_get_network_rtmp_server();
// the deamon st-thread will update it. // the deamon st-thread will update it.

Some files were not shown because too many files have changed in this diff Show more