Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2014-11-21 14:19:48 +0800
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
01f0513bd729e839126648809b1560005151ed58
01f0513b
2 parents
aab53e06
aa69f619
Merge branch 'srs.master'
隐藏空白字符变更
内嵌
并排对比
正在显示
15 个修改的文件
包含
698 行增加
和
687 行删除
README.md
trunk/research/librtmp/srs_audio_raw_publish.c
trunk/research/librtmp/srs_bandwidth_check.c
trunk/research/librtmp/srs_detect_rtmp.c
trunk/research/librtmp/srs_flv_injecter.c
trunk/research/librtmp/srs_flv_parser.c
trunk/research/librtmp/srs_h264_raw_publish.c
trunk/research/librtmp/srs_ingest_flv.c
trunk/research/librtmp/srs_ingest_rtmp.c
trunk/research/librtmp/srs_play.c
trunk/research/librtmp/srs_publish.c
trunk/src/core/srs_core.hpp
trunk/src/libs/srs_librtmp.cpp
trunk/src/libs/srs_librtmp.hpp
trunk/src/srs/srs.upp
README.md
查看文件 @
01f0513
...
...
@@ -482,6 +482,7 @@ Supported operating systems and hardware:
*
2013-10-17, Created.
<br/>
## History
*
v2.0, 2014-11-21, srs-librtmp add rtmp prefix for rtmp/utils/human apis. 2.0.29.
*
v2.0, 2014-11-21, refine examples of srs-librtmp, add srs_print_rtmp_packet. 2.0.28.
*
v2.0, 2014-11-20, fix
[
#212
](
https://github.com/winlinvip/simple-rtmp-server/issues/212
)
, support publish audio raw frames. 2.0.27
*
v2.0, 2014-11-19, fix
[
#213
](
https://github.com/winlinvip/simple-rtmp-server/issues/213
)
, support compile
[
srs-librtmp on windows
](
https://github.com/winlinvip/srs.librtmp
)
,
[
bug #213
](
https://github.com/winlinvip/simple-rtmp-server/issues/213
)
. 2.0.26
...
...
trunk/research/librtmp/srs_audio_raw_publish.c
查看文件 @
01f0513
...
...
@@ -46,7 +46,7 @@ int read_audio_frame(char* audio_raw, int file_size, char** pp, char** pdata, in
char
*
p
=
*
pp
;
if
(
file_size
-
(
p
-
audio_raw
)
<
168
)
{
srs_
lib
_trace
(
"audio must be 160+8 bytes. left %d bytes."
,
srs_
human
_trace
(
"audio must be 160+8 bytes. left %d bytes."
,
file_size
-
(
p
-
audio_raw
));
return
-
1
;
}
...
...
@@ -83,32 +83,32 @@ int main(int argc, char** argv)
const
char
*
raw_file
=
argv
[
1
];
const
char
*
rtmp_url
=
argv
[
2
];
srs_
lib
_trace
(
"raw_file=%s, rtmp_url=%s"
,
raw_file
,
rtmp_url
);
srs_
human
_trace
(
"raw_file=%s, rtmp_url=%s"
,
raw_file
,
rtmp_url
);
// open file
int
raw_fd
=
open
(
raw_file
,
O_RDONLY
);
if
(
raw_fd
<
0
)
{
srs_
lib
_trace
(
"open audio raw file %s failed."
,
raw_fd
);
srs_
human
_trace
(
"open audio raw file %s failed."
,
raw_fd
);
goto
rtmp_destroy
;
}
off_t
file_size
=
lseek
(
raw_fd
,
0
,
SEEK_END
);
if
(
file_size
<=
0
)
{
srs_
lib
_trace
(
"audio raw file %s empty."
,
raw_file
);
srs_
human
_trace
(
"audio raw file %s empty."
,
raw_file
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"read entirely audio raw file, size=%dKB"
,
(
int
)(
file_size
/
1024
));
srs_
human
_trace
(
"read entirely audio raw file, size=%dKB"
,
(
int
)(
file_size
/
1024
));
char
*
audio_raw
=
(
char
*
)
malloc
(
file_size
);
if
(
!
audio_raw
)
{
srs_
lib
_trace
(
"alloc raw buffer failed for file %s."
,
raw_file
);
srs_
human
_trace
(
"alloc raw buffer failed for file %s."
,
raw_file
);
goto
rtmp_destroy
;
}
lseek
(
raw_fd
,
0
,
SEEK_SET
);
ssize_t
nb_read
=
0
;
if
((
nb_read
=
read
(
raw_fd
,
audio_raw
,
file_size
))
!=
file_size
)
{
srs_
lib
_trace
(
"buffer %s failed, expect=%dKB, actual=%dKB."
,
srs_
human
_trace
(
"buffer %s failed, expect=%dKB, actual=%dKB."
,
raw_file
,
(
int
)(
file_size
/
1024
),
(
int
)(
nb_read
/
1024
));
goto
rtmp_destroy
;
}
...
...
@@ -116,23 +116,23 @@ int main(int argc, char** argv)
// connect rtmp context
srs_rtmp_t
rtmp
=
srs_rtmp_create
(
rtmp_url
);
if
(
srs_simple_handshake
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"simple handshake failed."
);
if
(
srs_rtmp_handshake
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"simple handshake failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"simple handshake success"
);
srs_
human
_trace
(
"simple handshake success"
);
if
(
srs_connect_app
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"connect vhost/app failed."
);
if
(
srs_rtmp_connect_app
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"connect vhost/app failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"connect vhost/app success"
);
srs_
human
_trace
(
"connect vhost/app success"
);
if
(
srs_publish_stream
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"publish stream failed."
);
if
(
srs_rtmp_publish_stream
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"publish stream failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"publish stream success"
);
srs_
human
_trace
(
"publish stream success"
);
u_int32_t
timestamp
=
0
;
u_int32_t
time_delta
=
17
;
...
...
@@ -143,7 +143,7 @@ int main(int argc, char** argv)
char
*
data
=
NULL
;
int
size
=
0
;
if
(
read_audio_frame
(
audio_raw
,
file_size
,
&
p
,
&
data
,
&
size
)
<
0
)
{
srs_
lib
_trace
(
"read a frame from file buffer failed."
);
srs_
human
_trace
(
"read a frame from file buffer failed."
);
goto
rtmp_destroy
;
}
...
...
@@ -168,12 +168,12 @@ int main(int argc, char** argv)
sound_format
,
sound_rate
,
sound_size
,
sound_type
,
0
,
data
,
size
,
timestamp
)
!=
0
)
{
srs_
lib
_trace
(
"send audio raw data failed."
);
srs_
human
_trace
(
"send audio raw data failed."
);
goto
rtmp_destroy
;
}
srs_lib_trace
(
"sent packet: type=%s, time=%d, size=%d, codec=%d, rate=%d, sample=%d, channel=%d"
,
srs_type2string
(
SRS_RTMP_TYPE_AUDIO
),
timestamp
,
size
,
sound_format
,
sound_rate
,
sound_size
,
srs_human_trace
(
"sent packet: type=%s, time=%d, size=%d, codec=%d, rate=%d, sample=%d, channel=%d"
,
srs_human_flv_tag_type2string
(
SRS_RTMP_TYPE_AUDIO
),
timestamp
,
size
,
sound_format
,
sound_rate
,
sound_size
,
sound_type
);
// @remark, when use encode device, it not need to sleep.
...
...
trunk/research/librtmp/srs_bandwidth_check.c
查看文件 @
01f0513
...
...
@@ -21,7 +21,7 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
gcc srs_
bandwidth_check.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs
_bandwidth_check
gcc srs_
rtmp_bandwidth_check.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_rtmp
_bandwidth_check
*/
#include <stdio.h>
...
...
@@ -81,31 +81,31 @@ int main(int argc, char** argv)
rtmp
=
srs_rtmp_create2
(
argv
[
1
]);
srs_
lib
_trace
(
"bandwidth check/test url: %s"
,
argv
[
1
]);
srs_
human
_trace
(
"bandwidth check/test url: %s"
,
argv
[
1
]);
if
((
ret
=
srs_simple_handshake
(
rtmp
))
!=
0
)
{
srs_lib_trace
(
"simple handshake failed."
);
if
((
ret
=
srs_rtmp_handshake
(
rtmp
))
!=
0
)
{
srs_human_trace
(
"simple handshake failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"simple handshake success"
);
srs_
human
_trace
(
"simple handshake success"
);
if
((
ret
=
srs_connect_app2
(
rtmp
,
if
((
ret
=
srs_
rtmp_
connect_app2
(
rtmp
,
srs_server_ip
,
srs_server
,
srs_primary_authors
,
srs_version
,
&
srs_id
,
&
srs_pid
))
!=
0
)
{
srs_
lib
_trace
(
"connect vhost/app failed."
);
srs_
human
_trace
(
"connect vhost/app failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"connect vhost/app success"
);
srs_
human
_trace
(
"connect vhost/app success"
);
if
((
ret
=
srs_bandwidth_check
(
rtmp
,
if
((
ret
=
srs_
rtmp_
bandwidth_check
(
rtmp
,
&
start_time
,
&
end_time
,
&
play_kbps
,
&
publish_kbps
,
&
play_bytes
,
&
publish_bytes
,
&
play_duration
,
&
publish_duration
))
!=
0
)
{
srs_
lib
_trace
(
"bandwidth check/test failed."
);
srs_
human
_trace
(
"bandwidth check/test failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"bandwidth check/test success"
);
srs_
human
_trace
(
"bandwidth check/test success"
);
srs_
lib
_trace
(
"
\n
%s, %s
\n
"
srs_
human
_trace
(
"
\n
%s, %s
\n
"
"%s, %s, srs_pid=%d, srs_id=%d
\n
"
"duration: %dms(%d+%d)
\n
"
"play: %dkbps
\n
"
...
...
@@ -137,8 +137,8 @@ rtmp_destroy:
(
int
)(
end_time
-
start_time
),
play_duration
,
publish_duration
,
play_kbps
,
publish_kbps
);
srs_lib_trace
(
""
);
srs_lib_trace
(
"completed"
);
srs_human_trace
(
""
);
srs_human_trace
(
"completed"
);
return
ret
;
}
...
...
trunk/research/librtmp/srs_detect_rtmp.c
查看文件 @
01f0513
...
...
@@ -35,7 +35,7 @@ int main(int argc, char** argv)
srs_rtmp_t
rtmp
;
// time
int64_t
time_startup
=
srs_get_time_ms
();
int64_t
time_startup
=
srs_
utils_
get_time_ms
();
int64_t
time_dns_resolve
=
0
;
int64_t
time_socket_connect
=
0
;
int64_t
time_play_stream
=
0
;
...
...
@@ -80,60 +80,60 @@ int main(int argc, char** argv)
duration
=
atoi
(
argv
[
2
]);
timeout
=
atoi
(
argv
[
3
]);
srs_lib_trace
(
"rtmp url: %s"
,
rtmp_url
);
srs_lib_trace
(
"duration: %ds, timeout:%ds"
,
duration
,
timeout
);
srs_human_trace
(
"rtmp url: %s"
,
rtmp_url
);
srs_human_trace
(
"duration: %ds, timeout:%ds"
,
duration
,
timeout
);
if
(
duration
<=
0
||
timeout
<=
0
)
{
srs_
lib
_trace
(
"duration and timeout must be positive."
);
srs_
human
_trace
(
"duration and timeout must be positive."
);
exit
(
-
2
);
}
rtmp
=
srs_rtmp_create
(
rtmp_url
);
if
((
ret
=
__srs_dns_resolve
(
rtmp
))
!=
0
)
{
srs_lib_trace
(
"dns resolve failed. ret=%d"
,
ret
);
if
((
ret
=
__srs_rtmp_dns_resolve
(
rtmp
))
!=
0
)
{
srs_human_trace
(
"dns resolve failed. ret=%d"
,
ret
);
goto
rtmp_destroy
;
}
srs_lib_trace
(
"dns resolve success"
);
time_dns_resolve
=
srs_get_time_ms
();
srs_human_trace
(
"dns resolve success"
);
time_dns_resolve
=
srs_utils_get_time_ms
();
if
((
ret
=
__srs_connect_server
(
rtmp
))
!=
0
)
{
srs_lib_trace
(
"socket connect failed. ret=%d"
,
ret
);
if
((
ret
=
__srs_rtmp_connect_server
(
rtmp
))
!=
0
)
{
srs_human_trace
(
"socket connect failed. ret=%d"
,
ret
);
goto
rtmp_destroy
;
}
srs_lib_trace
(
"socket connect success"
);
time_socket_connect
=
srs_get_time_ms
();
srs_human_trace
(
"socket connect success"
);
time_socket_connect
=
srs_utils_get_time_ms
();
if
((
ret
=
__srs_do_simple_handshake
(
rtmp
))
!=
0
)
{
srs_lib_trace
(
"do simple handshake failed. ret=%d"
,
ret
);
if
((
ret
=
__srs_rtmp_do_simple_handshake
(
rtmp
))
!=
0
)
{
srs_human_trace
(
"do simple handshake failed. ret=%d"
,
ret
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"do simple handshake success"
);
srs_
human
_trace
(
"do simple handshake success"
);
if
((
ret
=
srs_connect_app
(
rtmp
))
!=
0
)
{
srs_lib_trace
(
"connect vhost/app failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_connect_app
(
rtmp
))
!=
0
)
{
srs_human_trace
(
"connect vhost/app failed. ret=%d"
,
ret
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"connect vhost/app success"
);
srs_
human
_trace
(
"connect vhost/app success"
);
if
((
ret
=
srs_play_stream
(
rtmp
))
!=
0
)
{
srs_lib_trace
(
"play stream failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_play_stream
(
rtmp
))
!=
0
)
{
srs_human_trace
(
"play stream failed. ret=%d"
,
ret
);
goto
rtmp_destroy
;
}
srs_lib_trace
(
"play stream success"
);
time_play_stream
=
srs_get_time_ms
();
srs_human_trace
(
"play stream success"
);
time_play_stream
=
srs_utils_get_time_ms
();
for
(;;)
{
if
((
ret
=
srs_read_packet
(
rtmp
,
&
type
,
&
timestamp
,
&
data
,
&
size
))
!=
0
)
{
srs_lib_trace
(
"read packet failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_read_packet
(
rtmp
,
&
type
,
&
timestamp
,
&
data
,
&
size
))
!=
0
)
{
srs_human_trace
(
"read packet failed. ret=%d"
,
ret
);
goto
rtmp_destroy
;
}
srs_lib_trace
(
"got packet: type=%s, time=%d, size=%d"
,
srs_type2string
(
type
),
timestamp
,
size
);
srs_human_trace
(
"got packet: type=%s, time=%d, size=%d"
,
srs_human_flv_tag_type2string
(
type
),
timestamp
,
size
);
if
(
SRS_RTMP_TYPE_VIDEO
==
type
||
SRS_RTMP_TYPE_AUDIO
==
type
)
{
if
(
time_first_packet
<=
0
)
{
time_first_packet
=
srs_get_time_ms
();
time_first_packet
=
srs_
utils_
get_time_ms
();
}
if
(
basetime
<=
0
)
{
basetime
=
timestamp
;
...
...
@@ -142,23 +142,23 @@ int main(int argc, char** argv)
free
(
data
);
if
(
srs_get_time_ms
()
-
time_startup
>
timeout
*
1000
)
{
srs_lib_trace
(
"timeout, terminate."
);
if
(
srs_utils_get_time_ms
()
-
time_startup
>
timeout
*
1000
)
{
srs_human_trace
(
"timeout, terminate."
);
goto
rtmp_destroy
;
}
if
((
timestamp
-
basetime
)
>
duration
*
1000
)
{
srs_
lib
_trace
(
"duration exceed, terminate."
);
srs_
human
_trace
(
"duration exceed, terminate."
);
goto
rtmp_destroy
;
}
}
rtmp_destroy:
bytes_nsend
=
srs_get_nsend_bytes
(
rtmp
);
bytes_nrecv
=
srs_get_nrecv_bytes
(
rtmp
);
bytes_nsend
=
srs_utils_get_send_bytes
(
rtmp
);
bytes_nrecv
=
srs_utils_get_recv_bytes
(
rtmp
);
srs_rtmp_destroy
(
rtmp
);
time_cleanup
=
srs_get_time_ms
();
time_cleanup
=
srs_
utils_
get_time_ms
();
time_duration
=
(
int
)(
time_cleanup
-
time_startup
);
// print result to stderr.
...
...
@@ -197,8 +197,8 @@ rtmp_destroy:
"
\"
remark2
\"
:
\"
if code is not 0, user must ignore all data
\"
"
);
srs_lib_trace
(
""
);
srs_lib_trace
(
"completed"
);
srs_human_trace
(
""
);
srs_human_trace
(
"completed"
);
return
ret
;
}
...
...
trunk/research/librtmp/srs_flv_injecter.c
查看文件 @
01f0513
...
...
@@ -76,9 +76,9 @@ int main(int argc, char** argv)
tmp_file
=
(
char
*
)
malloc
(
tmp_file_size
);
snprintf
(
tmp_file
,
tmp_file_size
,
"%s.tmp"
,
out_flv_file
);
srs_lib_trace
(
"input: %s"
,
in_flv_file
);
srs_lib_trace
(
"output: %s"
,
out_flv_file
);
srs_lib_trace
(
"tmp_file: %s"
,
tmp_file
);
srs_human_trace
(
"input: %s"
,
in_flv_file
);
srs_human_trace
(
"output: %s"
,
out_flv_file
);
srs_human_trace
(
"tmp_file: %s"
,
tmp_file
);
ret
=
process
(
in_flv_file
,
tmp_file
,
&
ic
,
&
oc
);
...
...
@@ -89,13 +89,13 @@ int main(int argc, char** argv)
unlink
(
tmp_file
);
if
(
ret
==
ERROR_INJECTED
)
{
ret
=
0
;
srs_
lib
_trace
(
"file already injected."
);
srs_
human
_trace
(
"file already injected."
);
}
else
{
srs_
lib
_trace
(
"error, remove tmp file."
);
srs_
human
_trace
(
"error, remove tmp file."
);
}
}
else
{
rename
(
tmp_file
,
out_flv_file
);
srs_
lib
_trace
(
"completed, rename to %s"
,
out_flv_file
);
srs_
human
_trace
(
"completed, rename to %s"
,
out_flv_file
);
}
free
(
tmp_file
);
...
...
@@ -123,14 +123,14 @@ int process(const char* in_flv_file, const char* out_flv_file, srs_flv_t* pic, s
if
((
ic
=
srs_flv_open_read
(
in_flv_file
))
==
NULL
)
{
ret
=
2
;
srs_
lib
_trace
(
"open input flv file failed. ret=%d"
,
ret
);
srs_
human
_trace
(
"open input flv file failed. ret=%d"
,
ret
);
return
ret
;
}
*
pic
=
ic
;
if
((
oc
=
srs_flv_open_write
(
out_flv_file
))
==
NULL
)
{
ret
=
2
;
srs_
lib
_trace
(
"open output flv file failed. ret=%d"
,
ret
);
srs_
human
_trace
(
"open output flv file failed. ret=%d"
,
ret
);
return
ret
;
}
*
poc
=
oc
;
...
...
@@ -164,13 +164,13 @@ int parse_metadata(char* data, int size, srs_amf0_t* pname, srs_amf0_t* pdata)
*
pname
=
srs_amf0_parse
(
data
,
size
,
&
nparsed
);
if
(
*
pname
==
NULL
||
nparsed
>=
size
)
{
srs_
lib
_trace
(
"invalid amf0 name data."
);
srs_
human
_trace
(
"invalid amf0 name data."
);
return
-
1
;
}
*
pdata
=
srs_amf0_parse
(
data
+
nparsed
,
size
-
nparsed
,
&
nparsed
);
if
(
*
pdata
==
NULL
||
nparsed
>
size
)
{
srs_
lib
_trace
(
"invalid amf0 value data"
);
srs_
human
_trace
(
"invalid amf0 value data"
);
return
-
1
;
}
...
...
@@ -206,22 +206,22 @@ int build_keyframes(srs_flv_t ic, srs_amf0_t *pname, srs_amf0_t* pdata, srs_amf0
return
ret
;
}
srs_
lib
_trace
(
"build keyframe infos from flv"
);
srs_
human
_trace
(
"build keyframe infos from flv"
);
for
(;;)
{
offset
=
srs_flv_tellg
(
ic
);
// tag header
if
((
ret
=
srs_flv_read_tag_header
(
ic
,
&
type
,
&
size
,
&
timestamp
))
!=
0
)
{
if
(
srs_flv_is_eof
(
ret
))
{
srs_
lib
_trace
(
"parse completed."
);
srs_
human
_trace
(
"parse completed."
);
return
0
;
}
srs_
lib
_trace
(
"flv get packet failed. ret=%d"
,
ret
);
srs_
human
_trace
(
"flv get packet failed. ret=%d"
,
ret
);
return
ret
;
}
if
(
size
<=
0
)
{
srs_
lib
_trace
(
"invalid size=%d"
,
size
);
srs_
human
_trace
(
"invalid size=%d"
,
size
);
return
ret
;
}
...
...
@@ -343,20 +343,20 @@ int do_inject_flv(srs_flv_t ic, srs_flv_t oc, srs_amf0_t amf0_name, srs_amf0_t a
free
(
data
);
}
srs_
lib
_trace
(
"build keyframe infos from flv"
);
srs_
human
_trace
(
"build keyframe infos from flv"
);
for
(;;)
{
// tag header
if
((
ret
=
srs_flv_read_tag_header
(
ic
,
&
type
,
&
size
,
&
timestamp
))
!=
0
)
{
if
(
srs_flv_is_eof
(
ret
))
{
srs_
lib
_trace
(
"parse completed."
);
srs_
human
_trace
(
"parse completed."
);
return
0
;
}
srs_
lib
_trace
(
"flv get packet failed. ret=%d"
,
ret
);
srs_
human
_trace
(
"flv get packet failed. ret=%d"
,
ret
);
return
ret
;
}
if
(
size
<=
0
)
{
srs_
lib
_trace
(
"invalid size=%d"
,
size
);
srs_
human
_trace
(
"invalid size=%d"
,
size
);
break
;
}
...
...
trunk/research/librtmp/srs_flv_parser.c
查看文件 @
01f0513
...
...
@@ -61,11 +61,11 @@ int main(int argc, char** argv)
}
in_flv_file
=
argv
[
1
];
srs_
lib
_trace
(
"input: %s"
,
in_flv_file
);
srs_
human
_trace
(
"input: %s"
,
in_flv_file
);
if
((
flv
=
srs_flv_open_read
(
in_flv_file
))
==
NULL
)
{
ret
=
2
;
srs_
lib
_trace
(
"open flv file failed. ret=%d"
,
ret
);
srs_
human
_trace
(
"open flv file failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -141,44 +141,44 @@ int parse_flv(srs_flv_t flv)
return
ret
;
}
srs_
lib
_trace
(
"start parse flv"
);
srs_
human
_trace
(
"start parse flv"
);
for
(;;)
{
offset
=
srs_flv_tellg
(
flv
);
// tag header
if
((
ret
=
srs_flv_read_tag_header
(
flv
,
&
type
,
&
size
,
&
timestamp
))
!=
0
)
{
if
(
srs_flv_is_eof
(
ret
))
{
srs_
lib
_trace
(
"parse completed."
);
srs_
human
_trace
(
"parse completed."
);
return
0
;
}
srs_
lib
_trace
(
"flv get packet failed. ret=%d"
,
ret
);
srs_
human
_trace
(
"flv get packet failed. ret=%d"
,
ret
);
return
ret
;
}
if
(
size
<=
0
)
{
srs_
lib
_trace
(
"invalid size=%d"
,
size
);
srs_
human
_trace
(
"invalid size=%d"
,
size
);
break
;
}
data
=
(
char
*
)
malloc
(
size
);
if
((
ret
=
srs_flv_read_tag_data
(
flv
,
data
,
size
))
==
0
)
{
if
((
ret
=
srs_print_rtmp_packet
(
type
,
timestamp
,
data
,
size
))
==
0
)
{
if
((
ret
=
srs_
human_
print_rtmp_packet
(
type
,
timestamp
,
data
,
size
))
==
0
)
{
char
hbuf
[
48
];
char
tbuf
[
48
];
parse_bytes
(
data
,
size
,
hbuf
,
sizeof
(
hbuf
),
tbuf
,
sizeof
(
tbuf
),
16
);
srs_
raw_trace
(
"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
);
}
else
{
srs_
lib
_trace
(
"print packet failed. ret=%d"
,
ret
);
srs_
human
_trace
(
"print packet failed. ret=%d"
,
ret
);
}
}
else
{
srs_
lib
_trace
(
"read flv failed. ret=%d"
,
ret
);
srs_
human
_trace
(
"read flv failed. ret=%d"
,
ret
);
}
free
(
data
);
if
(
ret
!=
0
)
{
srs_
lib
_trace
(
"parse failed, ret=%d"
,
ret
);
srs_
human
_trace
(
"parse failed, ret=%d"
,
ret
);
return
ret
;
}
}
...
...
trunk/research/librtmp/srs_h264_raw_publish.c
查看文件 @
01f0513
...
...
@@ -44,7 +44,7 @@ int read_h264_frame(char* data, int size, char** pp, int* pnb_start_code, int fp
// we search the h264 frame from the buffer which cached the h264 data.
// please get h264 raw data from device, it always a encoded frame.
if
(
!
srs_h264_startswith_annexb
(
p
,
size
-
(
p
-
data
),
pnb_start_code
))
{
srs_
lib
_trace
(
"h264 raw data invalid."
);
srs_
human
_trace
(
"h264 raw data invalid."
);
return
-
1
;
}
...
...
@@ -63,7 +63,7 @@ int read_h264_frame(char* data, int size, char** pp, int* pnb_start_code, int fp
*
pp
=
p
;
*
frame_size
=
p
-
*
frame
;
if
(
*
frame_size
<=
0
)
{
srs_
lib
_trace
(
"h264 raw data invalid."
);
srs_
human
_trace
(
"h264 raw data invalid."
);
return
-
1
;
}
...
...
@@ -95,32 +95,32 @@ int main(int argc, char** argv)
const
char
*
raw_file
=
argv
[
1
];
const
char
*
rtmp_url
=
argv
[
2
];
srs_
lib
_trace
(
"raw_file=%s, rtmp_url=%s"
,
raw_file
,
rtmp_url
);
srs_
human
_trace
(
"raw_file=%s, rtmp_url=%s"
,
raw_file
,
rtmp_url
);
// open file
int
raw_fd
=
open
(
raw_file
,
O_RDONLY
);
if
(
raw_fd
<
0
)
{
srs_
lib
_trace
(
"open h264 raw file %s failed."
,
raw_fd
);
srs_
human
_trace
(
"open h264 raw file %s failed."
,
raw_fd
);
goto
rtmp_destroy
;
}
off_t
file_size
=
lseek
(
raw_fd
,
0
,
SEEK_END
);
if
(
file_size
<=
0
)
{
srs_
lib
_trace
(
"h264 raw file %s empty."
,
raw_file
);
srs_
human
_trace
(
"h264 raw file %s empty."
,
raw_file
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"read entirely h264 raw file, size=%dKB"
,
(
int
)(
file_size
/
1024
));
srs_
human
_trace
(
"read entirely h264 raw file, size=%dKB"
,
(
int
)(
file_size
/
1024
));
char
*
h264_raw
=
(
char
*
)
malloc
(
file_size
);
if
(
!
h264_raw
)
{
srs_
lib
_trace
(
"alloc raw buffer failed for file %s."
,
raw_file
);
srs_
human
_trace
(
"alloc raw buffer failed for file %s."
,
raw_file
);
goto
rtmp_destroy
;
}
lseek
(
raw_fd
,
0
,
SEEK_SET
);
ssize_t
nb_read
=
0
;
if
((
nb_read
=
read
(
raw_fd
,
h264_raw
,
file_size
))
!=
file_size
)
{
srs_
lib
_trace
(
"buffer %s failed, expect=%dKB, actual=%dKB."
,
srs_
human
_trace
(
"buffer %s failed, expect=%dKB, actual=%dKB."
,
raw_file
,
(
int
)(
file_size
/
1024
),
(
int
)(
nb_read
/
1024
));
goto
rtmp_destroy
;
}
...
...
@@ -128,23 +128,23 @@ int main(int argc, char** argv)
// connect rtmp context
srs_rtmp_t
rtmp
=
srs_rtmp_create
(
rtmp_url
);
if
(
srs_simple_handshake
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"simple handshake failed."
);
if
(
srs_rtmp_handshake
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"simple handshake failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"simple handshake success"
);
srs_
human
_trace
(
"simple handshake success"
);
if
(
srs_connect_app
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"connect vhost/app failed."
);
if
(
srs_rtmp_connect_app
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"connect vhost/app failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"connect vhost/app success"
);
srs_
human
_trace
(
"connect vhost/app success"
);
if
(
srs_publish_stream
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"publish stream failed."
);
if
(
srs_rtmp_publish_stream
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"publish stream failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"publish stream success"
);
srs_
human
_trace
(
"publish stream success"
);
u_int32_t
dts
=
0
;
u_int32_t
pts
=
0
;
...
...
@@ -161,7 +161,7 @@ int main(int argc, char** argv)
if
(
read_h264_frame
(
h264_raw
,
file_size
,
&
p
,
&
nb_start_code
,
fps
,
&
data
,
&
size
,
&
dts
,
&
pts
)
<
0
)
{
srs_
lib
_trace
(
"read a frame from file buffer failed."
);
srs_
human
_trace
(
"read a frame from file buffer failed."
);
goto
rtmp_destroy
;
}
...
...
@@ -169,13 +169,13 @@ int main(int argc, char** argv)
int
error
=
srs_h264_write_raw_frames
(
rtmp
,
data
,
size
,
dts
,
pts
);
if
(
error
!=
0
)
{
if
(
srs_h264_is_dvbsp_error
(
error
))
{
srs_
lib
_trace
(
"ignore drop video error, code=%d"
,
error
);
srs_
human
_trace
(
"ignore drop video error, code=%d"
,
error
);
}
else
if
(
srs_h264_is_duplicated_sps_error
(
error
))
{
srs_
lib
_trace
(
"ignore duplicated sps, code=%d"
,
error
);
srs_
human
_trace
(
"ignore duplicated sps, code=%d"
,
error
);
}
else
if
(
srs_h264_is_duplicated_pps_error
(
error
))
{
srs_
lib
_trace
(
"ignore duplicated pps, code=%d"
,
error
);
srs_
human
_trace
(
"ignore duplicated pps, code=%d"
,
error
);
}
else
{
srs_
lib
_trace
(
"send h264 raw data failed."
);
srs_
human
_trace
(
"send h264 raw data failed."
);
goto
rtmp_destroy
;
}
}
...
...
@@ -183,14 +183,14 @@ int main(int argc, char** argv)
// 5bits, 7.3.1 NAL unit syntax,
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
u_int8_t
nut
=
(
char
)
data
[
nb_start_code
]
&
0x1f
;
srs_lib_trace
(
"sent packet: type=%s, time=%d, size=%d, fps=%d, b[%d]=%#x(%s)"
,
srs_type2string
(
SRS_RTMP_TYPE_VIDEO
),
dts
,
size
,
fps
,
nb_start_code
,
(
char
)
data
[
nb_start_code
],
srs_human_trace
(
"sent packet: type=%s, time=%d, size=%d, fps=%d, b[%d]=%#x(%s)"
,
srs_human_flv_tag_type2string
(
SRS_RTMP_TYPE_VIDEO
),
dts
,
size
,
fps
,
nb_start_code
,
(
char
)
data
[
nb_start_code
],
(
nut
==
7
?
"SPS"
:
(
nut
==
8
?
"PPS"
:
(
nut
==
5
?
"I"
:
(
nut
==
1
?
"P"
:
"Unknown"
)))));
// @remark, when use encode device, it not need to sleep.
usleep
(
1000
/
fps
*
1000
);
}
srs_
lib
_trace
(
"h264 raw data completed"
);
srs_
human
_trace
(
"h264 raw data completed"
);
rtmp_destroy:
srs_rtmp_destroy
(
rtmp
);
...
...
trunk/research/librtmp/srs_ingest_flv.c
查看文件 @
01f0513
...
...
@@ -48,7 +48,7 @@ int main(int argc, char** argv)
int
ret
=
0
;
// main function
tools_main_entrance_startup_time
=
srs_get_time_ms
();
tools_main_entrance_startup_time
=
srs_
utils_
get_time_ms
();
// user option parse index.
int
opt
=
0
;
...
...
@@ -89,19 +89,19 @@ int main(int argc, char** argv)
}
}
srs_lib_trace
(
"input: %s"
,
in_flv_file
);
srs_lib_trace
(
"output: %s"
,
out_rtmp_url
);
srs_human_trace
(
"input: %s"
,
in_flv_file
);
srs_human_trace
(
"output: %s"
,
out_rtmp_url
);
if
((
flv
=
srs_flv_open_read
(
in_flv_file
))
==
NULL
)
{
ret
=
2
;
srs_
lib
_trace
(
"open flv file failed. ret=%d"
,
ret
);
srs_
human
_trace
(
"open flv file failed. ret=%d"
,
ret
);
return
ret
;
}
ortmp
=
srs_rtmp_create
(
out_rtmp_url
);
ret
=
proxy
(
flv
,
ortmp
);
srs_
lib
_trace
(
"ingest flv to RTMP completed"
);
srs_
human
_trace
(
"ingest flv to RTMP completed"
);
srs_rtmp_destroy
(
ortmp
);
srs_flv_close
(
flv
);
...
...
@@ -118,20 +118,20 @@ int do_proxy(srs_flv_t flv, srs_rtmp_t ortmp, int64_t re, int32_t* pstarttime, u
int
size
;
char
*
data
=
NULL
;
srs_
lib
_trace
(
"start ingest flv to RTMP stream"
);
srs_
human
_trace
(
"start ingest flv to RTMP stream"
);
for
(;;)
{
// tag header
if
((
ret
=
srs_flv_read_tag_header
(
flv
,
&
type
,
&
size
,
ptimestamp
))
!=
0
)
{
if
(
srs_flv_is_eof
(
ret
))
{
srs_
lib
_trace
(
"parse completed."
);
srs_
human
_trace
(
"parse completed."
);
return
0
;
}
srs_
lib
_trace
(
"flv get packet failed. ret=%d"
,
ret
);
srs_
human
_trace
(
"flv get packet failed. ret=%d"
,
ret
);
return
ret
;
}
if
(
size
<=
0
)
{
srs_
lib
_trace
(
"invalid size=%d"
,
size
);
srs_
human
_trace
(
"invalid size=%d"
,
size
);
break
;
}
...
...
@@ -143,13 +143,13 @@ int do_proxy(srs_flv_t flv, srs_rtmp_t ortmp, int64_t re, int32_t* pstarttime, u
u_int32_t
timestamp
=
*
ptimestamp
;
if
((
ret
=
srs_print_rtmp_packet
(
type
,
timestamp
,
data
,
size
))
!=
0
)
{
srs_lib_trace
(
"print packet failed. ret=%d"
,
ret
);
if
((
ret
=
srs_human_print_rtmp_packet
(
type
,
timestamp
,
data
,
size
))
!=
0
)
{
srs_human_trace
(
"print packet failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
srs_write_packet
(
ortmp
,
type
,
*
ptimestamp
,
data
,
size
))
!=
0
)
{
srs_lib_trace
(
"irtmp get packet failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_write_packet
(
ortmp
,
type
,
*
ptimestamp
,
data
,
size
))
!=
0
)
{
srs_human_trace
(
"irtmp get packet failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -191,23 +191,23 @@ int connect_oc(srs_rtmp_t ortmp)
{
int
ret
=
0
;
if
((
ret
=
srs_simple_handshake
(
ortmp
))
!=
0
)
{
srs_lib_trace
(
"ortmp simple handshake failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_handshake
(
ortmp
))
!=
0
)
{
srs_human_trace
(
"ortmp simple handshake failed. ret=%d"
,
ret
);
return
ret
;
}
srs_
lib
_trace
(
"ortmp simple handshake success"
);
srs_
human
_trace
(
"ortmp simple handshake success"
);
if
((
ret
=
srs_connect_app
(
ortmp
))
!=
0
)
{
srs_lib_trace
(
"ortmp connect vhost/app failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_connect_app
(
ortmp
))
!=
0
)
{
srs_human_trace
(
"ortmp connect vhost/app failed. ret=%d"
,
ret
);
return
ret
;
}
srs_
lib
_trace
(
"ortmp connect vhost/app success"
);
srs_
human
_trace
(
"ortmp connect vhost/app success"
);
if
((
ret
=
srs_publish_stream
(
ortmp
))
!=
0
)
{
srs_lib_trace
(
"ortmp publish stream failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_publish_stream
(
ortmp
))
!=
0
)
{
srs_human_trace
(
"ortmp publish stream failed. ret=%d"
,
ret
);
return
ret
;
}
srs_
lib
_trace
(
"ortmp publish stream success"
);
srs_
human
_trace
(
"ortmp publish stream success"
);
return
ret
;
}
...
...
@@ -215,20 +215,20 @@ int connect_oc(srs_rtmp_t ortmp)
int64_t
re_create
()
{
// if not very precise, we can directly use this as re.
int64_t
re
=
srs_get_time_ms
();
int64_t
re
=
srs_
utils_
get_time_ms
();
// use the starttime to get the deviation
int64_t
deviation
=
re
-
tools_main_entrance_startup_time
;
srs_
lib
_trace
(
"deviation is %d ms, pulse is %d ms"
,
(
int
)(
deviation
),
(
int
)(
RE_PULSE_MS
));
srs_
human
_trace
(
"deviation is %d ms, pulse is %d ms"
,
(
int
)(
deviation
),
(
int
)(
RE_PULSE_MS
));
// so, we adjust time to max(0, deviation)
// because the last pulse, we already sleeped
int
adjust
=
(
int
)(
deviation
);
if
(
adjust
>
0
)
{
srs_
lib
_trace
(
"adjust re time for %d ms"
,
adjust
);
srs_
human
_trace
(
"adjust re time for %d ms"
,
adjust
);
re
-=
adjust
;
}
else
{
srs_
lib
_trace
(
"no need to adjust re time"
);
srs_
human
_trace
(
"no need to adjust re time"
);
}
return
re
;
...
...
@@ -236,7 +236,7 @@ int64_t re_create()
void
re_update
(
int64_t
re
,
int32_t
starttime
,
u_int32_t
time
)
{
// send by pulse algorithm.
int64_t
now
=
srs_get_time_ms
();
int64_t
now
=
srs_
utils_
get_time_ms
();
int64_t
diff
=
time
-
starttime
-
(
now
-
re
);
if
(
diff
>
RE_PULSE_MS
)
{
usleep
(
diff
*
1000
);
...
...
@@ -246,10 +246,10 @@ void re_cleanup(int64_t re, int32_t starttime, u_int32_t time)
{
// for the last pulse, always sleep.
// for the virtual live encoder long time publishing.
int64_t
now
=
srs_get_time_ms
();
int64_t
now
=
srs_
utils_
get_time_ms
();
int64_t
diff
=
time
-
starttime
-
(
now
-
re
);
if
(
diff
>
0
)
{
srs_
lib
_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
);
usleep
(
diff
*
1000
);
}
...
...
trunk/research/librtmp/srs_ingest_rtmp.c
查看文件 @
01f0513
...
...
@@ -74,14 +74,14 @@ int main(int argc, char** argv)
}
}
srs_lib_trace
(
"input: %s"
,
in_rtmp_url
);
srs_lib_trace
(
"output: %s"
,
out_rtmp_url
);
srs_human_trace
(
"input: %s"
,
in_rtmp_url
);
srs_human_trace
(
"output: %s"
,
out_rtmp_url
);
irtmp
=
srs_rtmp_create
(
in_rtmp_url
);
ortmp
=
srs_rtmp_create
(
out_rtmp_url
);
ret
=
proxy
(
irtmp
,
ortmp
);
srs_
lib
_trace
(
"proxy completed"
);
srs_
human
_trace
(
"proxy completed"
);
srs_rtmp_destroy
(
irtmp
);
srs_rtmp_destroy
(
ortmp
);
...
...
@@ -106,24 +106,24 @@ int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp)
return
ret
;
}
srs_
lib
_trace
(
"start proxy RTMP stream"
);
srs_
human
_trace
(
"start proxy RTMP stream"
);
for
(;;)
{
if
((
ret
=
srs_read_packet
(
irtmp
,
&
type
,
&
timestamp
,
&
data
,
&
size
))
!=
0
)
{
srs_lib_trace
(
"irtmp get packet failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_read_packet
(
irtmp
,
&
type
,
&
timestamp
,
&
data
,
&
size
))
!=
0
)
{
srs_human_trace
(
"irtmp get packet failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
srs_print_rtmp_packet
(
type
,
timestamp
,
data
,
size
))
!=
0
)
{
srs_lib_trace
(
"print packet failed. ret=%d"
,
ret
);
if
((
ret
=
srs_human_print_rtmp_packet
(
type
,
timestamp
,
data
,
size
))
!=
0
)
{
srs_human_trace
(
"print packet failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
srs_write_packet
(
ortmp
,
type
,
timestamp
,
data
,
size
))
!=
0
)
{
srs_lib_trace
(
"irtmp get packet failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_write_packet
(
ortmp
,
type
,
timestamp
,
data
,
size
))
!=
0
)
{
srs_human_trace
(
"irtmp get packet failed. ret=%d"
,
ret
);
return
ret
;
}
srs_lib_verbose
(
"ortmp sent packet: type=%s, time=%d, size=%d"
,
srs_type2string
(
type
),
timestamp
,
size
);
srs_human_verbose
(
"ortmp sent packet: type=%s, time=%d, size=%d"
,
srs_human_flv_tag_type2string
(
type
),
timestamp
,
size
);
}
return
ret
;
...
...
@@ -133,23 +133,23 @@ int connect_ic(srs_rtmp_t irtmp)
{
int
ret
=
0
;
if
((
ret
=
srs_simple_handshake
(
irtmp
))
!=
0
)
{
srs_lib_trace
(
"irtmp simple handshake failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_handshake
(
irtmp
))
!=
0
)
{
srs_human_trace
(
"irtmp simple handshake failed. ret=%d"
,
ret
);
return
ret
;
}
srs_
lib
_trace
(
"irtmp simple handshake success"
);
srs_
human
_trace
(
"irtmp simple handshake success"
);
if
((
ret
=
srs_connect_app
(
irtmp
))
!=
0
)
{
srs_lib_trace
(
"irtmp connect vhost/app failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_connect_app
(
irtmp
))
!=
0
)
{
srs_human_trace
(
"irtmp connect vhost/app failed. ret=%d"
,
ret
);
return
ret
;
}
srs_
lib
_trace
(
"irtmp connect vhost/app success"
);
srs_
human
_trace
(
"irtmp connect vhost/app success"
);
if
((
ret
=
srs_play_stream
(
irtmp
))
!=
0
)
{
srs_lib_trace
(
"irtmp play stream failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_play_stream
(
irtmp
))
!=
0
)
{
srs_human_trace
(
"irtmp play stream failed. ret=%d"
,
ret
);
return
ret
;
}
srs_
lib
_trace
(
"irtmp play stream success"
);
srs_
human
_trace
(
"irtmp play stream success"
);
return
ret
;
}
...
...
@@ -158,23 +158,23 @@ int connect_oc(srs_rtmp_t ortmp)
{
int
ret
=
0
;
if
((
ret
=
srs_simple_handshake
(
ortmp
))
!=
0
)
{
srs_lib_trace
(
"ortmp simple handshake failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_handshake
(
ortmp
))
!=
0
)
{
srs_human_trace
(
"ortmp simple handshake failed. ret=%d"
,
ret
);
return
ret
;
}
srs_
lib
_trace
(
"ortmp simple handshake success"
);
srs_
human
_trace
(
"ortmp simple handshake success"
);
if
((
ret
=
srs_connect_app
(
ortmp
))
!=
0
)
{
srs_lib_trace
(
"ortmp connect vhost/app failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_connect_app
(
ortmp
))
!=
0
)
{
srs_human_trace
(
"ortmp connect vhost/app failed. ret=%d"
,
ret
);
return
ret
;
}
srs_
lib
_trace
(
"ortmp connect vhost/app success"
);
srs_
human
_trace
(
"ortmp connect vhost/app success"
);
if
((
ret
=
srs_publish_stream
(
ortmp
))
!=
0
)
{
srs_lib_trace
(
"ortmp publish stream failed. ret=%d"
,
ret
);
if
((
ret
=
srs_rtmp_publish_stream
(
ortmp
))
!=
0
)
{
srs_human_trace
(
"ortmp publish stream failed. ret=%d"
,
ret
);
return
ret
;
}
srs_
lib
_trace
(
"ortmp publish stream success"
);
srs_
human
_trace
(
"ortmp publish stream success"
);
return
ret
;
}
...
...
trunk/research/librtmp/srs_play.c
查看文件 @
01f0513
...
...
@@ -44,26 +44,26 @@ int main(int argc, char** argv)
exit
(
-
1
);
}
srs_
lib
_trace
(
"rtmp url: %s"
,
argv
[
1
]);
srs_
human
_trace
(
"rtmp url: %s"
,
argv
[
1
]);
srs_rtmp_t
rtmp
=
srs_rtmp_create
(
argv
[
1
]);
if
(
srs_simple_handshake
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"simple handshake failed."
);
if
(
srs_rtmp_handshake
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"simple handshake failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"simple handshake success"
);
srs_
human
_trace
(
"simple handshake success"
);
if
(
srs_connect_app
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"connect vhost/app failed."
);
if
(
srs_rtmp_connect_app
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"connect vhost/app failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"connect vhost/app success"
);
srs_
human
_trace
(
"connect vhost/app success"
);
if
(
srs_play_stream
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"play stream failed."
);
if
(
srs_rtmp_play_stream
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"play stream failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"play stream success"
);
srs_
human
_trace
(
"play stream success"
);
for
(;;)
{
int
size
;
...
...
@@ -71,11 +71,11 @@ int main(int argc, char** argv)
char
*
data
;
u_int32_t
timestamp
;
if
(
srs_read_packet
(
rtmp
,
&
type
,
&
timestamp
,
&
data
,
&
size
)
!=
0
)
{
if
(
srs_r
tmp_r
ead_packet
(
rtmp
,
&
type
,
&
timestamp
,
&
data
,
&
size
)
!=
0
)
{
goto
rtmp_destroy
;
}
if
(
srs_print_rtmp_packet
(
type
,
timestamp
,
data
,
size
)
!=
0
)
{
if
(
srs_
human_
print_rtmp_packet
(
type
,
timestamp
,
data
,
size
)
!=
0
)
{
goto
rtmp_destroy
;
}
...
...
trunk/research/librtmp/srs_publish.c
查看文件 @
01f0513
...
...
@@ -47,31 +47,31 @@ int main(int argc, char** argv)
// warn it .
// @see: https://github.com/winlinvip/simple-rtmp-server/issues/126
srs_
lib
_trace
(
"
\033
[33m%s
\033
[0m"
,
srs_
human
_trace
(
"
\033
[33m%s
\033
[0m"
,
"[warning] it's only a sample to use librtmp. "
"please never use it to publish and test forward/transcode/edge/HLS whatever. "
"you should refer to this tool to use the srs-librtmp to publish the real media stream."
"read about: https://github.com/winlinvip/simple-rtmp-server/issues/126"
);
srs_
lib
_trace
(
"rtmp url: %s"
,
argv
[
1
]);
srs_
human
_trace
(
"rtmp url: %s"
,
argv
[
1
]);
srs_rtmp_t
rtmp
=
srs_rtmp_create
(
argv
[
1
]);
if
(
srs_simple_handshake
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"simple handshake failed."
);
if
(
srs_rtmp_handshake
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"simple handshake failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"simple handshake success"
);
srs_
human
_trace
(
"simple handshake success"
);
if
(
srs_connect_app
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"connect vhost/app failed."
);
if
(
srs_rtmp_connect_app
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"connect vhost/app failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"connect vhost/app success"
);
srs_
human
_trace
(
"connect vhost/app success"
);
if
(
srs_publish_stream
(
rtmp
)
!=
0
)
{
srs_lib_trace
(
"publish stream failed."
);
if
(
srs_rtmp_publish_stream
(
rtmp
)
!=
0
)
{
srs_human_trace
(
"publish stream failed."
);
goto
rtmp_destroy
;
}
srs_
lib
_trace
(
"publish stream success"
);
srs_
human
_trace
(
"publish stream success"
);
u_int32_t
timestamp
=
0
;
for
(;;)
{
...
...
@@ -81,11 +81,11 @@ int main(int argc, char** argv)
timestamp
+=
40
;
if
(
srs_write_packet
(
rtmp
,
type
,
timestamp
,
data
,
size
)
!=
0
)
{
if
(
srs_
rtmp_
write_packet
(
rtmp
,
type
,
timestamp
,
data
,
size
)
!=
0
)
{
goto
rtmp_destroy
;
}
srs_lib_trace
(
"sent packet: type=%s, time=%d, size=%d"
,
srs_type2string
(
type
),
timestamp
,
size
);
srs_human_trace
(
"sent packet: type=%s, time=%d, size=%d"
,
srs_human_flv_tag_type2string
(
type
),
timestamp
,
size
);
usleep
(
40
*
1000
);
}
...
...
trunk/src/core/srs_core.hpp
查看文件 @
01f0513
...
...
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
#define VERSION_REVISION 2
8
#define VERSION_REVISION 2
9
// server info.
#define RTMP_SIG_SRS_KEY "SRS"
#define RTMP_SIG_SRS_ROLE "origin/edge server"
...
...
trunk/src/libs/srs_librtmp.cpp
查看文件 @
01f0513
...
...
@@ -514,6 +514,21 @@ int srs_librtmp_context_connect(Context* context)
extern
"C"
{
#endif
int
srs_version_major
()
{
return
VERSION_MAJOR
;
}
int
srs_version_minor
()
{
return
VERSION_MINOR
;
}
int
srs_version_revision
()
{
return
VERSION_REVISION
;
}
srs_rtmp_t
srs_rtmp_create
(
const
char
*
url
)
{
Context
*
context
=
new
Context
();
...
...
@@ -541,26 +556,26 @@ void srs_rtmp_destroy(srs_rtmp_t rtmp)
srs_freep
(
context
);
}
int
srs_
simple
_handshake
(
srs_rtmp_t
rtmp
)
int
srs_
rtmp
_handshake
(
srs_rtmp_t
rtmp
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
__srs_dns_resolve
(
rtmp
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
__srs_
rtmp_
dns_resolve
(
rtmp
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
__srs_connect_server
(
rtmp
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
__srs_
rtmp_
connect_server
(
rtmp
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
__srs_do_simple_handshake
(
rtmp
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
__srs_
rtmp_
do_simple_handshake
(
rtmp
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
int
__srs_dns_resolve
(
srs_rtmp_t
rtmp
)
int
__srs_
rtmp_
dns_resolve
(
srs_rtmp_t
rtmp
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -579,7 +594,7 @@ int __srs_dns_resolve(srs_rtmp_t rtmp)
return
ret
;
}
int
__srs_connect_server
(
srs_rtmp_t
rtmp
)
int
__srs_
rtmp_
connect_server
(
srs_rtmp_t
rtmp
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -593,7 +608,7 @@ int __srs_connect_server(srs_rtmp_t rtmp)
return
ret
;
}
int
__srs_do_simple_handshake
(
srs_rtmp_t
rtmp
)
int
__srs_
rtmp_
do_simple_handshake
(
srs_rtmp_t
rtmp
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -613,7 +628,7 @@ int __srs_do_simple_handshake(srs_rtmp_t rtmp)
return
ret
;
}
int
srs_connect_app
(
srs_rtmp_t
rtmp
)
int
srs_
rtmp_
connect_app
(
srs_rtmp_t
rtmp
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -634,7 +649,7 @@ int srs_connect_app(srs_rtmp_t rtmp)
return
ret
;
}
int
srs_connect_app2
(
srs_rtmp_t
rtmp
,
int
srs_
rtmp_
connect_app2
(
srs_rtmp_t
rtmp
,
char
srs_server_ip
[
128
],
char
srs_server
[
128
],
char
srs_primary_authors
[
128
],
char
srs_version
[
32
],
int
*
srs_id
,
int
*
srs_pid
)
{
...
...
@@ -670,7 +685,7 @@ int srs_connect_app2(srs_rtmp_t rtmp,
return
ret
;
}
int
srs_play_stream
(
srs_rtmp_t
rtmp
)
int
srs_
rtmp_
play_stream
(
srs_rtmp_t
rtmp
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -687,7 +702,7 @@ int srs_play_stream(srs_rtmp_t rtmp)
return
ret
;
}
int
srs_publish_stream
(
srs_rtmp_t
rtmp
)
int
srs_
rtmp_
publish_stream
(
srs_rtmp_t
rtmp
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -701,24 +716,7 @@ int srs_publish_stream(srs_rtmp_t rtmp)
return
ret
;
}
const
char
*
srs_type2string
(
char
type
)
{
static
const
char
*
audio
=
"Audio"
;
static
const
char
*
video
=
"Video"
;
static
const
char
*
data
=
"Data"
;
static
const
char
*
unknown
=
"Unknown"
;
switch
(
type
)
{
case
SRS_RTMP_TYPE_AUDIO
:
return
audio
;
case
SRS_RTMP_TYPE_VIDEO
:
return
video
;
case
SRS_RTMP_TYPE_SCRIPT
:
return
data
;
default
:
return
unknown
;
}
return
unknown
;
}
int
srs_bandwidth_check
(
srs_rtmp_t
rtmp
,
int
srs_rtmp_bandwidth_check
(
srs_rtmp_t
rtmp
,
int64_t
*
start_time
,
int64_t
*
end_time
,
int
*
play_kbps
,
int
*
publish_kbps
,
int
*
play_bytes
,
int
*
publish_bytes
,
...
...
@@ -754,7 +752,7 @@ int srs_bandwidth_check(srs_rtmp_t rtmp,
return
ret
;
}
int
srs_read_packet
(
srs_rtmp_t
rtmp
,
char
*
type
,
u_int32_t
*
timestamp
,
char
**
data
,
int
*
size
)
int
srs_r
tmp_r
ead_packet
(
srs_rtmp_t
rtmp
,
char
*
type
,
u_int32_t
*
timestamp
,
char
**
data
,
int
*
size
)
{
*
type
=
0
;
*
timestamp
=
0
;
...
...
@@ -809,7 +807,7 @@ int srs_read_packet(srs_rtmp_t rtmp, char* type, u_int32_t* timestamp, char** da
return
ret
;
}
int
srs_write_packet
(
srs_rtmp_t
rtmp
,
char
type
,
u_int32_t
timestamp
,
char
*
data
,
int
size
)
int
srs_
rtmp_
write_packet
(
srs_rtmp_t
rtmp
,
char
type
,
u_int32_t
timestamp
,
char
*
data
,
int
size
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -860,267 +858,6 @@ int srs_write_packet(srs_rtmp_t rtmp, char type, u_int32_t timestamp, char* data
return
ret
;
}
int
srs_version_major
()
{
return
VERSION_MAJOR
;
}
int
srs_version_minor
()
{
return
VERSION_MINOR
;
}
int
srs_version_revision
()
{
return
VERSION_REVISION
;
}
int64_t
srs_get_time_ms
()
{
srs_update_system_time_ms
();
return
srs_get_system_time_ms
();
}
int64_t
srs_get_nsend_bytes
(
srs_rtmp_t
rtmp
)
{
srs_assert
(
rtmp
!=
NULL
);
Context
*
context
=
(
Context
*
)
rtmp
;
return
context
->
rtmp
->
get_send_bytes
();
}
int64_t
srs_get_nrecv_bytes
(
srs_rtmp_t
rtmp
)
{
srs_assert
(
rtmp
!=
NULL
);
Context
*
context
=
(
Context
*
)
rtmp
;
return
context
->
rtmp
->
get_recv_bytes
();
}
int
srs_parse_timestamp
(
u_int32_t
time
,
char
type
,
char
*
data
,
int
size
,
u_int32_t
*
ppts
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
type
!=
SRS_RTMP_TYPE_VIDEO
)
{
*
ppts
=
time
;
return
ret
;
}
if
(
!
SrsFlvCodec
::
video_is_h264
(
data
,
size
))
{
return
ERROR_FLV_INVALID_VIDEO_TAG
;
}
if
(
SrsFlvCodec
::
video_is_sequence_header
(
data
,
size
))
{
*
ppts
=
time
;
return
ret
;
}
// 1bytes, frame type and codec id.
// 1bytes, avc packet type.
// 3bytes, cts, composition time,
// pts = dts + cts, or
// cts = pts - dts.
if
(
size
<
5
)
{
return
ERROR_FLV_INVALID_VIDEO_TAG
;
}
u_int32_t
cts
=
0
;
char
*
p
=
data
+
2
;
char
*
pp
=
(
char
*
)
&
cts
;
pp
[
2
]
=
*
p
++
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
*
ppts
=
time
+
cts
;
return
ret
;
}
char
srs_get_codec_id
(
char
*
data
,
int
size
)
{
if
(
size
<
1
)
{
return
0
;
}
char
codec_id
=
data
[
0
];
codec_id
=
codec_id
&
0x0F
;
return
codec_id
;
}
const
char
*
srs_code_id2string
(
char
codec_id
)
{
static
const
char
*
h263
=
"H.263"
;
static
const
char
*
screen
=
"Screen"
;
static
const
char
*
vp6
=
"VP6"
;
static
const
char
*
vp6_alpha
=
"VP6Alpha"
;
static
const
char
*
screen2
=
"Screen2"
;
static
const
char
*
h264
=
"H.264"
;
static
const
char
*
unknown
=
"Unknown"
;
switch
(
codec_id
)
{
case
2
:
return
h263
;
case
3
:
return
screen
;
case
4
:
return
vp6
;
case
5
:
return
vp6_alpha
;
case
6
:
return
screen2
;
case
7
:
return
h264
;
default
:
return
unknown
;
}
return
unknown
;
}
char
srs_get_avc_packet_type
(
char
*
data
,
int
size
)
{
if
(
size
<
2
)
{
return
-
1
;
}
if
(
!
SrsFlvCodec
::
video_is_h264
(
data
,
size
))
{
return
-
1
;
}
u_int8_t
avc_packet_type
=
data
[
1
];
if
(
avc_packet_type
>
2
)
{
return
-
1
;
}
return
avc_packet_type
;
}
const
char
*
srs_avc_packet2string
(
char
avc_packet_type
)
{
static
const
char
*
sps_pps
=
"SpsPps"
;
static
const
char
*
nalu
=
"Nalu"
;
static
const
char
*
sps_pps_end
=
"SpsPpsEnd"
;
static
const
char
*
unknown
=
"Unknown"
;
switch
(
avc_packet_type
)
{
case
0
:
return
sps_pps
;
case
1
:
return
nalu
;
case
2
:
return
sps_pps_end
;
default
:
return
unknown
;
}
return
unknown
;
}
char
srs_get_frame_type
(
char
*
data
,
int
size
)
{
if
(
size
<
1
)
{
return
-
1
;
}
if
(
!
SrsFlvCodec
::
video_is_h264
(
data
,
size
))
{
return
-
1
;
}
u_int8_t
frame_type
=
data
[
0
];
frame_type
=
(
frame_type
>>
4
)
&
0x0f
;
if
(
frame_type
<
1
||
frame_type
>
5
)
{
return
-
1
;
}
return
frame_type
;
}
const
char
*
srs_frame_type2string
(
char
frame_type
)
{
static
const
char
*
keyframe
=
"I"
;
static
const
char
*
interframe
=
"P/B"
;
static
const
char
*
disposable_interframe
=
"DI"
;
static
const
char
*
generated_keyframe
=
"GI"
;
static
const
char
*
video_infoframe
=
"VI"
;
static
const
char
*
unknown
=
"Unknown"
;
switch
(
frame_type
)
{
case
1
:
return
keyframe
;
case
2
:
return
interframe
;
case
3
:
return
disposable_interframe
;
case
4
:
return
generated_keyframe
;
case
5
:
return
video_infoframe
;
default
:
return
unknown
;
}
return
unknown
;
}
int
srs_print_rtmp_packet
(
char
type
,
u_int32_t
timestamp
,
char
*
data
,
int
size
)
{
int
ret
=
ERROR_SUCCESS
;
u_int32_t
pts
;
if
(
srs_parse_timestamp
(
timestamp
,
type
,
data
,
size
,
&
pts
)
!=
0
)
{
return
ret
;
}
if
(
type
==
SRS_RTMP_TYPE_VIDEO
)
{
srs_lib_trace
(
"Video packet type=%s, dts=%d, pts=%d, size=%d, %s(%s,%s)"
,
srs_type2string
(
type
),
timestamp
,
pts
,
size
,
srs_code_id2string
(
srs_get_codec_id
(
data
,
size
)),
srs_avc_packet2string
(
srs_get_avc_packet_type
(
data
,
size
)),
srs_frame_type2string
(
srs_get_frame_type
(
data
,
size
))
);
}
else
if
(
type
==
SRS_RTMP_TYPE_AUDIO
)
{
srs_lib_trace
(
"Audio packet type=%s, dts=%d, pts=%d, size=%d"
,
srs_type2string
(
type
),
timestamp
,
pts
,
size
);
}
else
if
(
type
==
SRS_RTMP_TYPE_SCRIPT
)
{
srs_lib_verbose
(
"Data packet type=%s, time=%d, size=%d"
,
srs_type2string
(
type
),
timestamp
,
size
);
int
nparsed
=
0
;
while
(
nparsed
<
size
)
{
int
nb_parsed_this
=
0
;
srs_amf0_t
amf0
=
srs_amf0_parse
(
data
+
nparsed
,
size
-
nparsed
,
&
nb_parsed_this
);
if
(
amf0
==
NULL
)
{
break
;
}
nparsed
+=
nb_parsed_this
;
char
*
amf0_str
=
NULL
;
srs_raw_trace
(
"%s"
,
srs_amf0_human_print
(
amf0
,
&
amf0_str
,
NULL
));
srs_amf0_free_bytes
(
amf0_str
);
}
}
else
{
srs_lib_trace
(
"Unknown packet type=%s, dts=%d, pts=%d, size=%d"
,
srs_type2string
(
type
),
timestamp
,
pts
,
size
);
}
return
ret
;
}
const
char
*
srs_format_time
()
{
struct
timeval
tv
;
static
char
buf
[
23
];
memset
(
buf
,
0
,
sizeof
(
buf
));
// clock time
if
(
gettimeofday
(
&
tv
,
NULL
)
==
-
1
)
{
return
buf
;
}
// to calendar time
struct
tm
*
tm
;
if
((
tm
=
localtime
((
const
time_t
*
)
&
tv
.
tv_sec
))
==
NULL
)
{
return
buf
;
}
snprintf
(
buf
,
sizeof
(
buf
),
"%d-%02d-%02d %02d:%02d:%02d.%03d"
,
1900
+
tm
->
tm_year
,
1
+
tm
->
tm_mon
,
tm
->
tm_mday
,
tm
->
tm_hour
,
tm
->
tm_min
,
tm
->
tm_sec
,
(
int
)(
tv
.
tv_usec
/
1000
));
// for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213
buf
[
sizeof
(
buf
)
-
1
]
=
0
;
return
buf
;
}
struct
FlvContext
{
SrsFileReader
reader
;
...
...
@@ -1574,25 +1311,14 @@ srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index)
return
(
srs_amf0_t
)
obj
->
at
(
index
);
}
void
srs_amf0_strict_array_append
(
srs_amf0_t
amf0
,
srs_amf0_t
value
)
{
SrsAmf0Any
*
any
=
(
SrsAmf0Any
*
)
amf0
;
srs_assert
(
any
->
is_strict_array
());
SrsAmf0StrictArray
*
obj
=
(
SrsAmf0StrictArray
*
)
amf0
;
any
=
(
SrsAmf0Any
*
)
value
;
obj
->
append
(
any
);
}
char
*
srs_amf0_human_print
(
srs_amf0_t
amf0
,
char
**
pdata
,
int
*
psize
)
{
if
(
!
amf0
)
{
return
NULL
;
}
void
srs_amf0_strict_array_append
(
srs_amf0_t
amf0
,
srs_amf0_t
value
)
{
SrsAmf0Any
*
any
=
(
SrsAmf0Any
*
)
amf0
;
return
any
->
human_print
(
pdata
,
psize
);
srs_assert
(
any
->
is_strict_array
());
SrsAmf0StrictArray
*
obj
=
(
SrsAmf0StrictArray
*
)
amf0
;
any
=
(
SrsAmf0Any
*
)
value
;
obj
->
append
(
any
);
}
/**
...
...
@@ -1630,7 +1356,7 @@ int srs_audio_write_raw_frame(srs_rtmp_t rtmp,
memcpy
(
p
,
frame
,
frame_size
);
return
srs_write_packet
(
context
,
SRS_RTMP_TYPE_AUDIO
,
timestamp
,
data
,
size
);
return
srs_
rtmp_
write_packet
(
context
,
SRS_RTMP_TYPE_AUDIO
,
timestamp
,
data
,
size
);
}
/**
...
...
@@ -1677,7 +1403,7 @@ int __srs_write_h264_packet(Context* context,
// h.264 raw data.
memcpy
(
p
,
h264_raw_data
,
h264_raw_size
);
return
srs_write_packet
(
context
,
SRS_RTMP_TYPE_VIDEO
,
timestamp
,
data
,
size
);
return
srs_
rtmp_
write_packet
(
context
,
SRS_RTMP_TYPE_VIDEO
,
timestamp
,
data
,
size
);
}
/**
...
...
@@ -1986,6 +1712,280 @@ int srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_
return
srs_avc_startswith_annexb
(
&
stream
,
pnb_start_code
);
}
int64_t
srs_utils_get_time_ms
()
{
srs_update_system_time_ms
();
return
srs_get_system_time_ms
();
}
int64_t
srs_utils_get_send_bytes
(
srs_rtmp_t
rtmp
)
{
srs_assert
(
rtmp
!=
NULL
);
Context
*
context
=
(
Context
*
)
rtmp
;
return
context
->
rtmp
->
get_send_bytes
();
}
int64_t
srs_utils_get_recv_bytes
(
srs_rtmp_t
rtmp
)
{
srs_assert
(
rtmp
!=
NULL
);
Context
*
context
=
(
Context
*
)
rtmp
;
return
context
->
rtmp
->
get_recv_bytes
();
}
int
srs_utils_parse_timestamp
(
u_int32_t
time
,
char
type
,
char
*
data
,
int
size
,
u_int32_t
*
ppts
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
type
!=
SRS_RTMP_TYPE_VIDEO
)
{
*
ppts
=
time
;
return
ret
;
}
if
(
!
SrsFlvCodec
::
video_is_h264
(
data
,
size
))
{
return
ERROR_FLV_INVALID_VIDEO_TAG
;
}
if
(
SrsFlvCodec
::
video_is_sequence_header
(
data
,
size
))
{
*
ppts
=
time
;
return
ret
;
}
// 1bytes, frame type and codec id.
// 1bytes, avc packet type.
// 3bytes, cts, composition time,
// pts = dts + cts, or
// cts = pts - dts.
if
(
size
<
5
)
{
return
ERROR_FLV_INVALID_VIDEO_TAG
;
}
u_int32_t
cts
=
0
;
char
*
p
=
data
+
2
;
char
*
pp
=
(
char
*
)
&
cts
;
pp
[
2
]
=
*
p
++
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
*
ppts
=
time
+
cts
;
return
ret
;
}
char
srs_utils_get_flv_video_codec_id
(
char
*
data
,
int
size
)
{
if
(
size
<
1
)
{
return
0
;
}
char
codec_id
=
data
[
0
];
codec_id
=
codec_id
&
0x0F
;
return
codec_id
;
}
char
srs_utils_get_flv_video_avc_packet_type
(
char
*
data
,
int
size
)
{
if
(
size
<
2
)
{
return
-
1
;
}
if
(
!
SrsFlvCodec
::
video_is_h264
(
data
,
size
))
{
return
-
1
;
}
u_int8_t
avc_packet_type
=
data
[
1
];
if
(
avc_packet_type
>
2
)
{
return
-
1
;
}
return
avc_packet_type
;
}
char
srs_utils_get_flv_video_frame_type
(
char
*
data
,
int
size
)
{
if
(
size
<
1
)
{
return
-
1
;
}
if
(
!
SrsFlvCodec
::
video_is_h264
(
data
,
size
))
{
return
-
1
;
}
u_int8_t
frame_type
=
data
[
0
];
frame_type
=
(
frame_type
>>
4
)
&
0x0f
;
if
(
frame_type
<
1
||
frame_type
>
5
)
{
return
-
1
;
}
return
frame_type
;
}
char
*
srs_human_amf0_print
(
srs_amf0_t
amf0
,
char
**
pdata
,
int
*
psize
)
{
if
(
!
amf0
)
{
return
NULL
;
}
SrsAmf0Any
*
any
=
(
SrsAmf0Any
*
)
amf0
;
return
any
->
human_print
(
pdata
,
psize
);
}
const
char
*
srs_human_flv_tag_type2string
(
char
type
)
{
static
const
char
*
audio
=
"Audio"
;
static
const
char
*
video
=
"Video"
;
static
const
char
*
data
=
"Data"
;
static
const
char
*
unknown
=
"Unknown"
;
switch
(
type
)
{
case
SRS_RTMP_TYPE_AUDIO
:
return
audio
;
case
SRS_RTMP_TYPE_VIDEO
:
return
video
;
case
SRS_RTMP_TYPE_SCRIPT
:
return
data
;
default:
return
unknown
;
}
return
unknown
;
}
const
char
*
srs_human_flv_video_codec_id2string
(
char
codec_id
)
{
static
const
char
*
h263
=
"H.263"
;
static
const
char
*
screen
=
"Screen"
;
static
const
char
*
vp6
=
"VP6"
;
static
const
char
*
vp6_alpha
=
"VP6Alpha"
;
static
const
char
*
screen2
=
"Screen2"
;
static
const
char
*
h264
=
"H.264"
;
static
const
char
*
unknown
=
"Unknown"
;
switch
(
codec_id
)
{
case
2
:
return
h263
;
case
3
:
return
screen
;
case
4
:
return
vp6
;
case
5
:
return
vp6_alpha
;
case
6
:
return
screen2
;
case
7
:
return
h264
;
default:
return
unknown
;
}
return
unknown
;
}
const
char
*
srs_human_flv_video_avc_packet_type2string
(
char
avc_packet_type
)
{
static
const
char
*
sps_pps
=
"SpsPps"
;
static
const
char
*
nalu
=
"Nalu"
;
static
const
char
*
sps_pps_end
=
"SpsPpsEnd"
;
static
const
char
*
unknown
=
"Unknown"
;
switch
(
avc_packet_type
)
{
case
0
:
return
sps_pps
;
case
1
:
return
nalu
;
case
2
:
return
sps_pps_end
;
default:
return
unknown
;
}
return
unknown
;
}
const
char
*
srs_human_flv_video_frame_type2string
(
char
frame_type
)
{
static
const
char
*
keyframe
=
"I"
;
static
const
char
*
interframe
=
"P/B"
;
static
const
char
*
disposable_interframe
=
"DI"
;
static
const
char
*
generated_keyframe
=
"GI"
;
static
const
char
*
video_infoframe
=
"VI"
;
static
const
char
*
unknown
=
"Unknown"
;
switch
(
frame_type
)
{
case
1
:
return
keyframe
;
case
2
:
return
interframe
;
case
3
:
return
disposable_interframe
;
case
4
:
return
generated_keyframe
;
case
5
:
return
video_infoframe
;
default:
return
unknown
;
}
return
unknown
;
}
int
srs_human_print_rtmp_packet
(
char
type
,
u_int32_t
timestamp
,
char
*
data
,
int
size
)
{
int
ret
=
ERROR_SUCCESS
;
u_int32_t
pts
;
if
(
srs_utils_parse_timestamp
(
timestamp
,
type
,
data
,
size
,
&
pts
)
!=
0
)
{
return
ret
;
}
if
(
type
==
SRS_RTMP_TYPE_VIDEO
)
{
srs_human_trace
(
"Video packet type=%s, dts=%d, pts=%d, size=%d, %s(%s,%s)"
,
srs_human_flv_tag_type2string
(
type
),
timestamp
,
pts
,
size
,
srs_human_flv_video_codec_id2string
(
srs_utils_get_flv_video_codec_id
(
data
,
size
)),
srs_human_flv_video_avc_packet_type2string
(
srs_utils_get_flv_video_avc_packet_type
(
data
,
size
)),
srs_human_flv_video_frame_type2string
(
srs_utils_get_flv_video_frame_type
(
data
,
size
))
);
}
else
if
(
type
==
SRS_RTMP_TYPE_AUDIO
)
{
srs_human_trace
(
"Audio packet type=%s, dts=%d, pts=%d, size=%d"
,
srs_human_flv_tag_type2string
(
type
),
timestamp
,
pts
,
size
);
}
else
if
(
type
==
SRS_RTMP_TYPE_SCRIPT
)
{
srs_human_verbose
(
"Data packet type=%s, time=%d, size=%d"
,
srs_human_flv_tag_type2string
(
type
),
timestamp
,
size
);
int
nparsed
=
0
;
while
(
nparsed
<
size
)
{
int
nb_parsed_this
=
0
;
srs_amf0_t
amf0
=
srs_amf0_parse
(
data
+
nparsed
,
size
-
nparsed
,
&
nb_parsed_this
);
if
(
amf0
==
NULL
)
{
break
;
}
nparsed
+=
nb_parsed_this
;
char
*
amf0_str
=
NULL
;
srs_human_raw
(
"%s"
,
srs_human_amf0_print
(
amf0
,
&
amf0_str
,
NULL
));
srs_amf0_free_bytes
(
amf0_str
);
}
}
else
{
srs_human_trace
(
"Unknown packet type=%s, dts=%d, pts=%d, size=%d"
,
srs_human_flv_tag_type2string
(
type
),
timestamp
,
pts
,
size
);
}
return
ret
;
}
const
char
*
srs_human_format_time
()
{
struct
timeval
tv
;
static
char
buf
[
23
];
memset
(
buf
,
0
,
sizeof
(
buf
));
// clock time
if
(
gettimeofday
(
&
tv
,
NULL
)
==
-
1
)
{
return
buf
;
}
// to calendar time
struct
tm
*
tm
;
if
((
tm
=
localtime
((
const
time_t
*
)
&
tv
.
tv_sec
))
==
NULL
)
{
return
buf
;
}
snprintf
(
buf
,
sizeof
(
buf
),
"%d-%02d-%02d %02d:%02d:%02d.%03d"
,
1900
+
tm
->
tm_year
,
1
+
tm
->
tm_mon
,
tm
->
tm_mday
,
tm
->
tm_hour
,
tm
->
tm_min
,
tm
->
tm_sec
,
(
int
)(
tv
.
tv_usec
/
1000
));
// for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213
buf
[
sizeof
(
buf
)
-
1
]
=
0
;
return
buf
;
}
#ifdef __cplusplus
}
#endif
...
...
trunk/src/libs/srs_librtmp.hpp
查看文件 @
01f0513
...
...
@@ -86,6 +86,15 @@ extern "C"{
/*************************************************************
**************************************************************
* srs-librtmp version
**************************************************************
*************************************************************/
extern
int
srs_version_major
();
extern
int
srs_version_minor
();
extern
int
srs_version_revision
();
/*************************************************************
**************************************************************
* RTMP protocol context
**************************************************************
*************************************************************/
...
...
@@ -134,19 +143,19 @@ extern void srs_rtmp_destroy(srs_rtmp_t rtmp);
* not depends on ssl.
*/
/**
* srs_simple_handshake equals to invoke:
* __srs_dns_resolve()
* __srs_connect_server()
* __srs_do_simple_handshake()
* srs_rtmp_handshake equals to invoke:
* __srs_rtmp_dns_resolve()
* __srs_rtmp_connect_server()
* __srs_rtmp_do_simple_handshake()
* user can use these functions if needed.
*/
extern
int
srs_
simple
_handshake
(
srs_rtmp_t
rtmp
);
extern
int
srs_
rtmp
_handshake
(
srs_rtmp_t
rtmp
);
// parse uri, create socket, resolve host
extern
int
__srs_dns_resolve
(
srs_rtmp_t
rtmp
);
extern
int
__srs_
rtmp_
dns_resolve
(
srs_rtmp_t
rtmp
);
// connect socket to server
extern
int
__srs_connect_server
(
srs_rtmp_t
rtmp
);
extern
int
__srs_
rtmp_
connect_server
(
srs_rtmp_t
rtmp
);
// do simple handshake over socket.
extern
int
__srs_do_simple_handshake
(
srs_rtmp_t
rtmp
);
extern
int
__srs_
rtmp_
do_simple_handshake
(
srs_rtmp_t
rtmp
);
/**
* connect to rtmp vhost/app
...
...
@@ -156,7 +165,7 @@ extern int __srs_do_simple_handshake(srs_rtmp_t rtmp);
*
* @return 0, success; otherswise, failed.
*/
extern
int
srs_connect_app
(
srs_rtmp_t
rtmp
);
extern
int
srs_
rtmp_
connect_app
(
srs_rtmp_t
rtmp
);
/**
* connect to server, get the debug srs info.
...
...
@@ -171,7 +180,7 @@ extern int srs_connect_app(srs_rtmp_t rtmp);
*
* @return 0, success; otherswise, failed.
*/
extern
int
srs_connect_app2
(
srs_rtmp_t
rtmp
,
extern
int
srs_
rtmp_
connect_app2
(
srs_rtmp_t
rtmp
,
char
srs_server_ip
[
128
],
char
srs_server
[
128
],
char
srs_primary_authors
[
128
],
char
srs_version
[
32
],
int
*
srs_id
,
int
*
srs_pid
);
...
...
@@ -183,7 +192,7 @@ extern int srs_connect_app2(srs_rtmp_t rtmp,
* next: destroy
* @return 0, success; otherwise, failed.
*/
extern
int
srs_play_stream
(
srs_rtmp_t
rtmp
);
extern
int
srs_
rtmp_
play_stream
(
srs_rtmp_t
rtmp
);
/**
* publish a live stream.
...
...
@@ -192,7 +201,7 @@ extern int srs_play_stream(srs_rtmp_t rtmp);
* next: destroy
* @return 0, success; otherwise, failed.
*/
extern
int
srs_publish_stream
(
srs_rtmp_t
rtmp
);
extern
int
srs_
rtmp_
publish_stream
(
srs_rtmp_t
rtmp
);
/**
* do bandwidth check with srs server.
...
...
@@ -209,7 +218,7 @@ extern int srs_publish_stream(srs_rtmp_t rtmp);
*
* @return 0, success; otherswise, failed.
*/
extern
int
srs_bandwidth_check
(
srs_rtmp_t
rtmp
,
extern
int
srs_
rtmp_
bandwidth_check
(
srs_rtmp_t
rtmp
,
int64_t
*
start_time
,
int64_t
*
end_time
,
int
*
play_kbps
,
int
*
publish_kbps
,
int
*
play_bytes
,
int
*
publish_bytes
,
...
...
@@ -226,16 +235,6 @@ extern int srs_bandwidth_check(srs_rtmp_t rtmp,
// 18 = script data
#define SRS_RTMP_TYPE_SCRIPT 18
/**
* convert the flv tag type to string.
* SRS_RTMP_TYPE_AUDIO to "Audio"
* SRS_RTMP_TYPE_VIDEO to "Video"
* SRS_RTMP_TYPE_SCRIPT to "Data"
* otherwise, "Unknown"
* @remark user never free the return char*,
* it's static shared const string.
*/
extern
const
char
*
srs_type2string
(
char
type
);
/**
* read a audio/video/script-data packet from rtmp stream.
* @param type, output the packet type, macros:
* SRS_RTMP_TYPE_AUDIO, FlvTagAudio
...
...
@@ -256,146 +255,13 @@ extern const char* srs_type2string(char type);
*
* @return 0, success; otherswise, failed.
*/
extern
int
srs_read_packet
(
srs_rtmp_t
rtmp
,
extern
int
srs_r
tmp_r
ead_packet
(
srs_rtmp_t
rtmp
,
char
*
type
,
u_int32_t
*
timestamp
,
char
**
data
,
int
*
size
);
extern
int
srs_write_packet
(
srs_rtmp_t
rtmp
,
extern
int
srs_
rtmp_
write_packet
(
srs_rtmp_t
rtmp
,
char
type
,
u_int32_t
timestamp
,
char
*
data
,
int
size
);
// get protocol stack version
extern
int
srs_version_major
();
extern
int
srs_version_minor
();
extern
int
srs_version_revision
();
/*************************************************************
**************************************************************
* utilities
**************************************************************
*************************************************************/
/**
* get the current system time in ms.
* use gettimeofday() to get system time.
*/
extern
int64_t
srs_get_time_ms
();
/**
* get the send bytes.
*/
extern
int64_t
srs_get_nsend_bytes
(
srs_rtmp_t
rtmp
);
/**
* get the recv bytes.
*/
extern
int64_t
srs_get_nrecv_bytes
(
srs_rtmp_t
rtmp
);
/**
* parse the dts and pts by time in header and data in tag,
* or to parse the RTMP packet by srs_read_packet().
*
* @param time, the timestamp of tag, read by srs_flv_read_tag_header().
* @param type, the type of tag, read by srs_flv_read_tag_header().
* @param data, the data of tag, read by srs_flv_read_tag_data().
* @param size, the size of tag, read by srs_flv_read_tag_header().
* @param ppts, output the pts in ms,
*
* @return 0, success; otherswise, failed.
* @remark, the dts always equals to @param time.
* @remark, the pts=dts for audio or data.
* @remark, video only support h.264.
*/
extern
int
srs_parse_timestamp
(
u_int32_t
time
,
char
type
,
char
*
data
,
int
size
,
u_int32_t
*
ppts
);
/**
* get the CodecID of video tag.
* Codec Identifier. The following values are defined:
* 2 = Sorenson H.263
* 3 = Screen video
* 4 = On2 VP6
* 5 = On2 VP6 with alpha channel
* 6 = Screen video version 2
* 7 = AVC
* @return the code id. 0 for error.
*/
extern
char
srs_get_codec_id
(
char
*
data
,
int
size
);
/**
* get the codec id string.
* H.263 = Sorenson H.263
* Screen = Screen video
* VP6 = On2 VP6
* VP6Alpha = On2 VP6 with alpha channel
* Screen2 = Screen video version 2
* H.264 = AVC
* otherwise, "Unknown"
* @remark user never free the return char*,
* it's static shared const string.
*/
extern
const
char
*
srs_code_id2string
(
char
codec_id
);
/**
* get the AVCPacketType of video tag.
* The following values are defined:
* 0 = AVC sequence header
* 1 = AVC NALU
* 2 = AVC end of sequence (lower level NALU sequence ender is
* not required or supported)
* @return the avc packet type. -1(0xff) for error.
*/
extern
char
srs_get_avc_packet_type
(
char
*
data
,
int
size
);
/**
* get the avc packet type string.
* SpsPps = AVC sequence header
* Nalu = AVC NALU
* SpsPpsEnd = AVC end of sequence
* otherwise, "Unknown"
* @remark user never free the return char*,
* it's static shared const string.
*/
extern
const
char
*
srs_avc_packet2string
(
char
avc_packet_type
);
/**
* get the FrameType of video tag.
* Type of video frame. The following values are defined:
* 1 = key frame (for AVC, a seekable frame)
* 2 = inter frame (for AVC, a non-seekable frame)
* 3 = disposable inter frame (H.263 only)
* 4 = generated key frame (reserved for server use only)
* 5 = video info/command frame
* @return the frame type. 0 for error.
*/
extern
char
srs_get_frame_type
(
char
*
data
,
int
size
);
/**
* get the frame type string.
* I = key frame (for AVC, a seekable frame)
* P/B = inter frame (for AVC, a non-seekable frame)
* DI = disposable inter frame (H.263 only)
* GI = generated key frame (reserved for server use only)
* VI = video info/command frame
* otherwise, "Unknown"
* @remark user never free the return char*,
* it's static shared const string.
*/
extern
const
char
*
srs_frame_type2string
(
char
frame_type
);
/**
* print the rtmp packet, use srs_lib_trace/srs_lib_verbose for packet,
* and use srs_raw_trace for script data body.
* @return an error code for parse the timetstamp to dts and pts.
*/
extern
int
srs_print_rtmp_packet
(
char
type
,
u_int32_t
timestamp
,
char
*
data
,
int
size
);
// log to console, for use srs-librtmp application.
extern
const
char
*
srs_format_time
();
#define srs_lib_trace(msg, ...) printf("[%s] ", srs_format_time());printf(msg, ##__VA_ARGS__);printf("\n")
#define srs_lib_verbose(msg, ...) printf("[%s] ", srs_format_time());printf(msg, ##__VA_ARGS__);printf("\n")
#define srs_raw_trace(msg, ...) printf(msg, ##__VA_ARGS__)
/*************************************************************
**************************************************************
* flv codec
...
...
@@ -553,13 +419,6 @@ extern void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name,
extern
int
srs_amf0_strict_array_property_count
(
srs_amf0_t
amf0
);
extern
srs_amf0_t
srs_amf0_strict_array_property_at
(
srs_amf0_t
amf0
,
int
index
);
extern
void
srs_amf0_strict_array_append
(
srs_amf0_t
amf0
,
srs_amf0_t
value
);
/**
* human readable print
* @param pdata, output the heap data, NULL to ignore.
* user must use srs_amf0_free_bytes to free it.
* @return return the *pdata for print. NULL to ignore.
*/
extern
char
*
srs_amf0_human_print
(
srs_amf0_t
amf0
,
char
**
pdata
,
int
*
psize
);
/*************************************************************
**************************************************************
...
...
@@ -724,6 +583,157 @@ extern int srs_h264_startswith_annexb(
int
*
pnb_start_code
);
/*************************************************************
**************************************************************
* utilities
**************************************************************
*************************************************************/
/**
* get the current system time in ms.
* use gettimeofday() to get system time.
*/
extern
int64_t
srs_utils_get_time_ms
();
/**
* get the send bytes.
*/
extern
int64_t
srs_utils_get_send_bytes
(
srs_rtmp_t
rtmp
);
/**
* get the recv bytes.
*/
extern
int64_t
srs_utils_get_recv_bytes
(
srs_rtmp_t
rtmp
);
/**
* parse the dts and pts by time in header and data in tag,
* or to parse the RTMP packet by srs_rtmp_read_packet().
*
* @param time, the timestamp of tag, read by srs_flv_read_tag_header().
* @param type, the type of tag, read by srs_flv_read_tag_header().
* @param data, the data of tag, read by srs_flv_read_tag_data().
* @param size, the size of tag, read by srs_flv_read_tag_header().
* @param ppts, output the pts in ms,
*
* @return 0, success; otherswise, failed.
* @remark, the dts always equals to @param time.
* @remark, the pts=dts for audio or data.
* @remark, video only support h.264.
*/
extern
int
srs_utils_parse_timestamp
(
u_int32_t
time
,
char
type
,
char
*
data
,
int
size
,
u_int32_t
*
ppts
);
/**
* get the CodecID of video tag.
* Codec Identifier. The following values are defined:
* 2 = Sorenson H.263
* 3 = Screen video
* 4 = On2 VP6
* 5 = On2 VP6 with alpha channel
* 6 = Screen video version 2
* 7 = AVC
* @return the code id. 0 for error.
*/
extern
char
srs_utils_get_flv_video_codec_id
(
char
*
data
,
int
size
);
/**
* get the AVCPacketType of video tag.
* The following values are defined:
* 0 = AVC sequence header
* 1 = AVC NALU
* 2 = AVC end of sequence (lower level NALU sequence ender is
* not required or supported)
* @return the avc packet type. -1(0xff) for error.
*/
extern
char
srs_utils_get_flv_video_avc_packet_type
(
char
*
data
,
int
size
);
/**
* get the FrameType of video tag.
* Type of video frame. The following values are defined:
* 1 = key frame (for AVC, a seekable frame)
* 2 = inter frame (for AVC, a non-seekable frame)
* 3 = disposable inter frame (H.263 only)
* 4 = generated key frame (reserved for server use only)
* 5 = video info/command frame
* @return the frame type. 0 for error.
*/
extern
char
srs_utils_get_flv_video_frame_type
(
char
*
data
,
int
size
);
/*************************************************************
**************************************************************
* human readable print.
**************************************************************
*************************************************************/
/**
* human readable print
* @param pdata, output the heap data, NULL to ignore.
* user must use srs_amf0_free_bytes to free it.
* @return return the *pdata for print. NULL to ignore.
*/
extern
char
*
srs_human_amf0_print
(
srs_amf0_t
amf0
,
char
**
pdata
,
int
*
psize
);
/**
* convert the flv tag type to string.
* SRS_RTMP_TYPE_AUDIO to "Audio"
* SRS_RTMP_TYPE_VIDEO to "Video"
* SRS_RTMP_TYPE_SCRIPT to "Data"
* otherwise, "Unknown"
* @remark user never free the return char*,
* it's static shared const string.
*/
extern
const
char
*
srs_human_flv_tag_type2string
(
char
type
);
/**
* get the codec id string.
* H.263 = Sorenson H.263
* Screen = Screen video
* VP6 = On2 VP6
* VP6Alpha = On2 VP6 with alpha channel
* Screen2 = Screen video version 2
* H.264 = AVC
* otherwise, "Unknown"
* @remark user never free the return char*,
* it's static shared const string.
*/
extern
const
char
*
srs_human_flv_video_codec_id2string
(
char
codec_id
);
/**
* get the avc packet type string.
* SpsPps = AVC sequence header
* Nalu = AVC NALU
* SpsPpsEnd = AVC end of sequence
* otherwise, "Unknown"
* @remark user never free the return char*,
* it's static shared const string.
*/
extern
const
char
*
srs_human_flv_video_avc_packet_type2string
(
char
avc_packet_type
);
/**
* get the frame type string.
* I = key frame (for AVC, a seekable frame)
* P/B = inter frame (for AVC, a non-seekable frame)
* DI = disposable inter frame (H.263 only)
* GI = generated key frame (reserved for server use only)
* VI = video info/command frame
* otherwise, "Unknown"
* @remark user never free the return char*,
* it's static shared const string.
*/
extern
const
char
*
srs_human_flv_video_frame_type2string
(
char
frame_type
);
/**
* print the rtmp packet, use srs_human_trace/srs_human_verbose for packet,
* and use srs_human_raw for script data body.
* @return an error code for parse the timetstamp to dts and pts.
*/
extern
int
srs_human_print_rtmp_packet
(
char
type
,
u_int32_t
timestamp
,
char
*
data
,
int
size
);
// log to console, for use srs-librtmp application.
extern
const
char
*
srs_human_format_time
();
#define srs_human_trace(msg, ...) printf("[%s] ", srs_human_format_time());printf(msg, ##__VA_ARGS__);printf("\n")
#define srs_human_verbose(msg, ...) printf("[%s] ", srs_human_format_time());printf(msg, ##__VA_ARGS__);printf("\n")
#define srs_human_raw(msg, ...) printf(msg, ##__VA_ARGS__)
#ifdef __cplusplus
}
#endif
...
...
trunk/src/srs/srs.upp
查看文件 @
01f0513
...
...
@@ -129,7 +129,7 @@ file
..\utest\srs_utest_reload.cpp,
research readonly separator,
..\..\research\librtmp\srs_audio_raw_publish.c,
..\..\research\librtmp\srs_bandwidth_check.c,
..\..\research\librtmp\srs_
rtmp_
bandwidth_check.c,
..\..\research\librtmp\srs_detect_rtmp.c,
..\..\research\librtmp\srs_flv_injecter.c,
..\..\research\librtmp\srs_flv_parser.c,
...
...
请
注册
或
登录
后发表评论