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 13:48:57 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
d9474d760076b1cd298c8317d82c8e266545ac6e
d9474d76
1 parent
a058eeeb
refine examples of srs-librtmp, add srs_print_rtmp_packet. 2.0.28.
隐藏空白字符变更
内嵌
并排对比
正在显示
8 个修改的文件
包含
284 行增加
和
101 行删除
README.md
trunk/research/librtmp/srs_flv_parser.c
trunk/research/librtmp/srs_ingest_flv.c
trunk/research/librtmp/srs_ingest_rtmp.c
trunk/research/librtmp/srs_play.c
trunk/src/core/srs_core.hpp
trunk/src/libs/srs_librtmp.cpp
trunk/src/libs/srs_librtmp.hpp
README.md
查看文件 @
d9474d7
...
...
@@ -482,6 +482,7 @@ Supported operating systems and hardware:
*
2013-10-17, Created.
<br/>
## History
*
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
*
v2.0, 2014-11-18, all wiki translated to English. 2.0.23.
...
...
trunk/research/librtmp/srs_flv_parser.c
查看文件 @
d9474d7
...
...
@@ -124,86 +124,6 @@ int parse_bytes(char* data, int size, char* hbuf, int hsize, char* tbuf, int tsi
}
}
#define FLV_HEADER_SIZE 11
int
parse_script_data
(
u_int32_t
timestamp
,
u_int32_t
pts
,
char
*
data
,
int
size
,
int64_t
offset
)
{
int
ret
=
0
;
char
hbuf
[
48
];
char
tbuf
[
48
];
int
amf0_size
=
0
;
int
nparsed
=
0
;
srs_amf0_t
amf0_name
;
char
*
amf0_name_str
=
NULL
;
srs_amf0_t
amf0_data
;
char
*
amf0_data_str
=
NULL
;
// bytes
parse_bytes
(
data
,
size
,
hbuf
,
sizeof
(
hbuf
),
tbuf
,
sizeof
(
tbuf
),
16
);
// amf0
amf0_name
=
srs_amf0_parse
(
data
,
size
,
&
nparsed
);
if
(
amf0_name
==
NULL
||
nparsed
>=
size
)
{
srs_lib_trace
(
"invalid amf0 name data."
);
return
-
1
;
}
amf0_data
=
srs_amf0_parse
(
data
+
nparsed
,
size
-
nparsed
,
&
nparsed
);
srs_lib_trace
(
"packet type=%s, dts=%d, pts=%d, size=%d, data-size=%d,
\n
"
"offset=%d
\n
[+00, +15] %s
\n
[-15, EOF] %s
\n
%s%s"
,
srs_type2string
(
SRS_RTMP_TYPE_SCRIPT
),
timestamp
,
pts
,
size
+
FLV_HEADER_SIZE
,
size
,
(
int
)
offset
,
hbuf
,
tbuf
,
srs_amf0_human_print
(
amf0_name
,
&
amf0_name_str
,
&
amf0_size
),
srs_amf0_human_print
(
amf0_data
,
&
amf0_data_str
,
&
amf0_size
));
srs_amf0_free
(
amf0_name
);
srs_amf0_free_bytes
(
amf0_name_str
);
srs_amf0_free
(
amf0_data
);
srs_amf0_free_bytes
(
amf0_data_str
);
return
ret
;
}
int
parse_audio_data
(
u_int32_t
timestamp
,
u_int32_t
pts
,
char
*
data
,
int
size
,
int64_t
offset
)
{
int
ret
=
0
;
char
hbuf
[
48
];
char
tbuf
[
48
];
// bytes
parse_bytes
(
data
,
size
,
hbuf
,
sizeof
(
hbuf
),
tbuf
,
sizeof
(
tbuf
),
16
);
srs_lib_trace
(
"packet type=%s, dts=%d, pts=%d, size=%d, data-size=%d,
\n
"
"offset=%d
\n
[+00, +15] %s
\n
[-15, EOF] %s
\n
"
,
srs_type2string
(
SRS_RTMP_TYPE_AUDIO
),
timestamp
,
pts
,
size
+
FLV_HEADER_SIZE
,
size
,
(
int
)
offset
,
hbuf
,
tbuf
);
return
ret
;
}
int
parse_video_data
(
u_int32_t
timestamp
,
u_int32_t
pts
,
char
*
data
,
int
size
,
int64_t
offset
)
{
int
ret
=
0
;
char
hbuf
[
48
];
char
tbuf
[
48
];
// bytes
parse_bytes
(
data
,
size
,
hbuf
,
sizeof
(
hbuf
),
tbuf
,
sizeof
(
tbuf
),
16
);
srs_lib_trace
(
"packet type=%s, dts=%d, pts=%d, size=%d, data-size=%d,
\n
"
"offset=%d
\n
[+00, +15] %s
\n
[-15, EOF] %s
\n
"
,
srs_type2string
(
SRS_RTMP_TYPE_VIDEO
),
timestamp
,
pts
,
size
+
FLV_HEADER_SIZE
,
size
,
(
int
)
offset
,
hbuf
,
tbuf
);
return
ret
;
}
int
parse_flv
(
srs_flv_t
flv
)
{
int
ret
=
0
;
...
...
@@ -240,19 +160,19 @@ int parse_flv(srs_flv_t flv)
break
;
}
u_int32_t
pts
=
0
;
data
=
(
char
*
)
malloc
(
size
);
if
((
ret
=
srs_flv_read_tag_data
(
flv
,
data
,
size
))
==
0
&&
(
ret
=
srs_parse_timestamp
(
timestamp
,
type
,
data
,
size
,
&
pts
))
==
0
)
{
if
(
type
==
SRS_RTMP_TYPE_AUDIO
)
{
ret
=
parse_audio_data
(
timestamp
,
pts
,
data
,
size
,
offset
);
}
else
if
(
type
==
SRS_RTMP_TYPE_VIDEO
)
{
ret
=
parse_video_data
(
timestamp
,
pts
,
data
,
size
,
offset
);
if
((
ret
=
srs_flv_read_tag_data
(
flv
,
data
,
size
))
==
0
)
{
if
((
ret
=
srs_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
"
"[+00, +15] %s
\n
[-15, EOF] %s
\n
"
,
(
int
)
offset
,
hbuf
,
tbuf
);
}
else
{
ret
=
parse_script_data
(
timestamp
,
pts
,
data
,
size
,
offs
et
);
srs_lib_trace
(
"print packet failed. ret=%d"
,
r
et
);
}
}
else
{
srs_lib_trace
(
"read flv failed. ret=%d"
,
ret
);
}
free
(
data
);
...
...
trunk/research/librtmp/srs_ingest_flv.c
查看文件 @
d9474d7
...
...
@@ -141,12 +141,17 @@ int do_proxy(srs_flv_t flv, srs_rtmp_t ortmp, int64_t re, int32_t* pstarttime, u
return
ret
;
}
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
);
return
ret
;
}
if
((
ret
=
srs_write_packet
(
ortmp
,
type
,
*
ptimestamp
,
data
,
size
))
!=
0
)
{
srs_lib_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
),
*
ptimestamp
,
size
);
if
(
*
pstarttime
<
0
)
{
*
pstarttime
=
*
ptimestamp
;
...
...
trunk/research/librtmp/srs_ingest_rtmp.c
查看文件 @
d9474d7
...
...
@@ -112,8 +112,11 @@ int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp)
srs_lib_trace
(
"irtmp get packet failed. ret=%d"
,
ret
);
return
ret
;
}
srs_lib_verbose
(
"irtmp got packet: type=%s, time=%d, size=%d"
,
srs_type2string
(
type
),
timestamp
,
size
);
if
((
ret
=
srs_print_rtmp_packet
(
type
,
timestamp
,
data
,
size
))
!=
0
)
{
srs_lib_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
);
...
...
trunk/research/librtmp/srs_play.c
查看文件 @
d9474d7
...
...
@@ -69,16 +69,15 @@ int main(int argc, char** argv)
int
size
;
char
type
;
char
*
data
;
u_int32_t
timestamp
,
pts
;
u_int32_t
timestamp
;
if
(
srs_read_packet
(
rtmp
,
&
type
,
&
timestamp
,
&
data
,
&
size
)
!=
0
)
{
goto
rtmp_destroy
;
}
if
(
srs_parse_timestamp
(
timestamp
,
type
,
data
,
size
,
&
pts
)
!=
0
)
{
if
(
srs_print_rtmp_packet
(
type
,
timestamp
,
data
,
size
)
!=
0
)
{
goto
rtmp_destroy
;
}
srs_lib_trace
(
"got packet: type=%s, dts=%d, pts=%d, size=%d"
,
srs_type2string
(
type
),
timestamp
,
pts
,
size
);
free
(
data
);
}
...
...
trunk/src/core/srs_core.hpp
查看文件 @
d9474d7
...
...
@@ -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
7
#define VERSION_REVISION 2
8
// server info.
#define RTMP_SIG_SRS_KEY "SRS"
#define RTMP_SIG_SRS_ROLE "origin/edge server"
...
...
trunk/src/libs/srs_librtmp.cpp
查看文件 @
d9474d7
...
...
@@ -936,6 +936,161 @@ int srs_parse_timestamp(
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
;
...
...
@@ -1171,7 +1326,9 @@ srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed)
return
amf0
;
}
*
nparsed
=
stream
.
pos
();
if
(
nparsed
)
{
*
nparsed
=
stream
.
pos
();
}
amf0
=
(
srs_amf0_t
)
any
;
return
amf0
;
...
...
@@ -1445,8 +1602,6 @@ int srs_audio_write_raw_frame(srs_rtmp_t rtmp,
char
sound_format
,
char
sound_rate
,
char
sound_size
,
char
sound_type
,
char
aac_packet_type
,
char
*
frame
,
int
frame_size
,
u_int32_t
timestamp
)
{
int
ret
=
ERROR_SUCCESS
;
Context
*
context
=
(
Context
*
)
rtmp
;
srs_assert
(
context
);
...
...
trunk/src/libs/srs_librtmp.hpp
查看文件 @
d9474d7
...
...
@@ -273,9 +273,22 @@ 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().
...
...
@@ -296,10 +309,92 @@ extern int srs_parse_timestamp(
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__)
/*************************************************************
**************************************************************
...
...
@@ -412,6 +507,11 @@ extern srs_flv_bool srs_flv_is_keyframe(char* data, int32_t size);
typedef
void
*
srs_amf0_t
;
typedef
int
srs_amf0_bool
;
typedef
double
srs_amf0_number
;
/**
* parse amf0 from data.
* @param nparsed, the parsed size, NULL to ignore.
* @return the parsed amf0 object. NULL for error.
*/
extern
srs_amf0_t
srs_amf0_parse
(
char
*
data
,
int
size
,
int
*
nparsed
);
extern
srs_amf0_t
srs_amf0_create_number
(
srs_amf0_number
value
);
extern
srs_amf0_t
srs_amf0_create_ecma_array
();
...
...
请
注册
或
登录
后发表评论