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:11:53 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
180106ce708e9c48610bcb3ab22e65babb8418af
180106ce
1 parent
10bc5399
refine librtmp, move the utils and human to end section.
隐藏空白字符变更
内嵌
并排对比
正在显示
2 个修改的文件
包含
503 行增加
和
503 行删除
trunk/src/libs/srs_librtmp.cpp
trunk/src/libs/srs_librtmp.hpp
trunk/src/libs/srs_librtmp.cpp
查看文件 @
180106c
...
...
@@ -858,117 +858,6 @@ int srs_version_revision()
return
VERSION_REVISION
;
}
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
;
}
struct
FlvContext
{
SrsFileReader
reader
;
...
...
@@ -1432,264 +1321,101 @@ void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value)
obj
->
append
(
any
);
}
char
*
srs_human_amf0_print
(
srs_amf0_t
amf0
,
char
**
pdata
,
int
*
psize
)
{
if
(
!
amf0
)
{
return
NULL
;
/**
* write audio raw frame to SRS.
*/
int
srs_audio_write_raw_frame
(
srs_rtmp_t
rtmp
,
char
sound_format
,
char
sound_rate
,
char
sound_size
,
char
sound_type
,
char
aac_packet_type
,
char
*
frame
,
int
frame_size
,
u_int32_t
timestamp
)
{
Context
*
context
=
(
Context
*
)
rtmp
;
srs_assert
(
context
);
// TODO: FIXME: for aac, must send the sequence header first.
// for audio frame, there is 1 or 2 bytes header:
// 1bytes, SoundFormat|SoundRate|SoundSize|SoundType
// 1bytes, AACPacketType for SoundFormat == 10
int
size
=
frame_size
+
1
;
if
(
aac_packet_type
==
SrsCodecAudioAAC
)
{
size
+=
1
;
}
char
*
data
=
new
char
[
size
];
char
*
p
=
data
;
SrsAmf0Any
*
any
=
(
SrsAmf0Any
*
)
amf0
;
u_int8_t
audio_header
=
sound_type
&
0x01
;
audio_header
|=
(
sound_size
<<
1
)
&
0x02
;
audio_header
|=
(
sound_rate
<<
2
)
&
0x0c
;
audio_header
|=
(
sound_format
<<
4
)
&
0xf0
;
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"
;
*
p
++
=
audio_header
;
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
;
if
(
aac_packet_type
==
SrsCodecAudioAAC
)
{
*
p
++
=
aac_packet_type
;
}
return
unknown
;
memcpy
(
p
,
frame
,
frame_size
);
return
srs_write_packet
(
context
,
SRS_RTMP_TYPE_AUDIO
,
timestamp
,
data
,
size
);
}
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"
;
/**
* write h264 packet, with rtmp header.
* @param frame_type, SrsCodecVideoAVCFrameKeyFrame or SrsCodecVideoAVCFrameInterFrame.
* @param avc_packet_type, SrsCodecVideoAVCTypeSequenceHeader or SrsCodecVideoAVCTypeNALU.
* @param h264_raw_data the h.264 raw data, user must free it.
*/
int
__srs_write_h264_packet
(
Context
*
context
,
int8_t
frame_type
,
int8_t
avc_packet_type
,
char
*
h264_raw_data
,
int
h264_raw_size
,
u_int32_t
dts
,
u_int32_t
pts
)
{
// the timestamp in rtmp message header is dts.
u_int32_t
timestamp
=
dts
;
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
;
}
// for h264 in RTMP video payload, there is 5bytes header:
// 1bytes, FrameType | CodecID
// 1bytes, AVCPacketType
// 3bytes, CompositionTime, the cts.
// @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
int
size
=
h264_raw_size
+
5
;
char
*
data
=
new
char
[
size
];
char
*
p
=
data
;
return
unknown
;
}
// @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
// Frame Type, Type of video frame.
// CodecID, Codec Identifier.
// set the rtmp header
*
p
++
=
(
frame_type
<<
4
)
|
SrsCodecVideoAVC
;
// AVCPacketType
*
p
++
=
avc_packet_type
;
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"
;
// CompositionTime
// pts = dts + cts, or
// cts = pts - dts.
// where cts is the header in rtmp video packet payload header.
u_int32_t
cts
=
pts
-
dts
;
char
*
pp
=
(
char
*
)
&
cts
;
*
p
++
=
pp
[
2
];
*
p
++
=
pp
[
1
];
*
p
++
=
pp
[
0
];
switch
(
avc_packet_type
)
{
case
0
:
return
sps_pps
;
case
1
:
return
nalu
;
case
2
:
return
sps_pps_end
;
default:
return
unknown
;
}
// h.264 raw data.
memcpy
(
p
,
h264_raw_data
,
h264_raw_size
);
return
unknown
;
return
srs_write_packet
(
context
,
SRS_RTMP_TYPE_VIDEO
,
timestamp
,
data
,
size
)
;
}
const
char
*
srs_human_flv_video_frame_type2string
(
char
frame_type
)
/**
* write the h264 sps/pps in context over RTMP.
*/
int
__srs_write_h264_sps_pps
(
Context
*
context
,
u_int32_t
dts
,
u_int32_t
pts
)
{
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"
;
int
ret
=
ERROR_SUCCESS
;
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
;
}
/**
* write audio raw frame to SRS.
*/
int
srs_audio_write_raw_frame
(
srs_rtmp_t
rtmp
,
char
sound_format
,
char
sound_rate
,
char
sound_size
,
char
sound_type
,
char
aac_packet_type
,
char
*
frame
,
int
frame_size
,
u_int32_t
timestamp
)
{
Context
*
context
=
(
Context
*
)
rtmp
;
srs_assert
(
context
);
// TODO: FIXME: for aac, must send the sequence header first.
// for audio frame, there is 1 or 2 bytes header:
// 1bytes, SoundFormat|SoundRate|SoundSize|SoundType
// 1bytes, AACPacketType for SoundFormat == 10
int
size
=
frame_size
+
1
;
if
(
aac_packet_type
==
SrsCodecAudioAAC
)
{
size
+=
1
;
}
char
*
data
=
new
char
[
size
];
char
*
p
=
data
;
u_int8_t
audio_header
=
sound_type
&
0x01
;
audio_header
|=
(
sound_size
<<
1
)
&
0x02
;
audio_header
|=
(
sound_rate
<<
2
)
&
0x0c
;
audio_header
|=
(
sound_format
<<
4
)
&
0xf0
;
*
p
++
=
audio_header
;
if
(
aac_packet_type
==
SrsCodecAudioAAC
)
{
*
p
++
=
aac_packet_type
;
}
memcpy
(
p
,
frame
,
frame_size
);
return
srs_write_packet
(
context
,
SRS_RTMP_TYPE_AUDIO
,
timestamp
,
data
,
size
);
}
/**
* write h264 packet, with rtmp header.
* @param frame_type, SrsCodecVideoAVCFrameKeyFrame or SrsCodecVideoAVCFrameInterFrame.
* @param avc_packet_type, SrsCodecVideoAVCTypeSequenceHeader or SrsCodecVideoAVCTypeNALU.
* @param h264_raw_data the h.264 raw data, user must free it.
*/
int
__srs_write_h264_packet
(
Context
*
context
,
int8_t
frame_type
,
int8_t
avc_packet_type
,
char
*
h264_raw_data
,
int
h264_raw_size
,
u_int32_t
dts
,
u_int32_t
pts
)
{
// the timestamp in rtmp message header is dts.
u_int32_t
timestamp
=
dts
;
// for h264 in RTMP video payload, there is 5bytes header:
// 1bytes, FrameType | CodecID
// 1bytes, AVCPacketType
// 3bytes, CompositionTime, the cts.
// @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
int
size
=
h264_raw_size
+
5
;
char
*
data
=
new
char
[
size
];
char
*
p
=
data
;
// @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78
// Frame Type, Type of video frame.
// CodecID, Codec Identifier.
// set the rtmp header
*
p
++
=
(
frame_type
<<
4
)
|
SrsCodecVideoAVC
;
// AVCPacketType
*
p
++
=
avc_packet_type
;
// CompositionTime
// pts = dts + cts, or
// cts = pts - dts.
// where cts is the header in rtmp video packet payload header.
u_int32_t
cts
=
pts
-
dts
;
char
*
pp
=
(
char
*
)
&
cts
;
*
p
++
=
pp
[
2
];
*
p
++
=
pp
[
1
];
*
p
++
=
pp
[
0
];
// h.264 raw data.
memcpy
(
p
,
h264_raw_data
,
h264_raw_size
);
return
srs_write_packet
(
context
,
SRS_RTMP_TYPE_VIDEO
,
timestamp
,
data
,
size
);
}
/**
* write the h264 sps/pps in context over RTMP.
*/
int
__srs_write_h264_sps_pps
(
Context
*
context
,
u_int32_t
dts
,
u_int32_t
pts
)
{
int
ret
=
ERROR_SUCCESS
;
// only send when both sps and pps changed.
if
(
!
context
->
h264_sps_changed
||
!
context
->
h264_pps_changed
)
{
return
ret
;
// only send when both sps and pps changed.
if
(
!
context
->
h264_sps_changed
||
!
context
->
h264_pps_changed
)
{
return
ret
;
}
// 5bytes sps/pps header:
...
...
@@ -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
查看文件 @
180106c
...
...
@@ -265,83 +265,6 @@ extern int srs_version_revision();
/*************************************************************
**************************************************************
* 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_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
);
/*************************************************************
**************************************************************
* flv codec
* @example /trunk/research/librtmp/srs_flv_injecter.c
* @example /trunk/research/librtmp/srs_flv_parser.c
...
...
@@ -500,80 +423,6 @@ extern void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value);
/*************************************************************
**************************************************************
* 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__)
/*************************************************************
**************************************************************
* audio raw codec
**************************************************************
*************************************************************/
...
...
@@ -735,6 +584,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_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
...
...
请
注册
或
登录
后发表评论