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
2015-04-03 23:17:50 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
70c59da1bfd41d08c1b958e65d101f20a4160687
70c59da1
1 parent
7e1749e0
enhanced avc decode, parse the sps get width+height. 2.0.156.
隐藏空白字符变更
内嵌
并排对比
正在显示
9 个修改的文件
包含
351 行增加
和
8 行删除
README.md
trunk/src/core/srs_core.hpp
trunk/src/kernel/srs_kernel_codec.cpp
trunk/src/kernel/srs_kernel_codec.hpp
trunk/src/kernel/srs_kernel_error.hpp
trunk/src/kernel/srs_kernel_stream.cpp
trunk/src/kernel/srs_kernel_stream.hpp
trunk/src/kernel/srs_kernel_utility.cpp
trunk/src/kernel/srs_kernel_utility.hpp
README.md
查看文件 @
70c59da
...
...
@@ -562,7 +562,8 @@ Supported operating systems and hardware:
### SRS 2.0 history
*
v2.0, 2015-03-30, for
[
#372
](
https://github.com/winlinvip/simple-rtmp-server/issues/372
)
, support transform vhost of edge 2.0.155.
*
v2.0, 2015-04-03, enhanced avc decode, parse the sps get width+height. 2.0.156.
*
v2.0, 2015-04-03, for
[
#372
](
https://github.com/winlinvip/simple-rtmp-server/issues/372
)
, support transform vhost of edge 2.0.155.
*
v2.0, 2015-03-30, for
[
#366
](
https://github.com/winlinvip/simple-rtmp-server/issues/366
)
, config hls to disable cleanup of ts. 2.0.154.
*
v2.0, 2015-03-31, support server cycle handler. 2.0.153.
*
v2.0, 2015-03-31, support on_hls for http hooks. 2.0.152.
...
...
trunk/src/core/srs_core.hpp
查看文件 @
70c59da
...
...
@@ -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 15
5
#define VERSION_REVISION 15
6
// server info.
#define RTMP_SIG_SRS_KEY "SRS"
...
...
trunk/src/kernel/srs_kernel_codec.cpp
查看文件 @
70c59da
...
...
@@ -31,6 +31,7 @@ using namespace std;
#include <srs_kernel_log.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_core_autofree.hpp>
string
srs_codec_video2str
(
SrsCodecVideo
codec
)
{
...
...
@@ -713,7 +714,8 @@ int SrsAvcAacCodec::avc_demux_sps_pps(SrsStream* stream)
return
ret
;
}
// 1 sps
// 1 sps, 7.3.2.1 Sequence parameter set RBSP syntax
// H.264-AVC-ISO_IEC_14496-10.pdf, page 45.
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"avc decode sequenc header sps failed. ret=%d"
,
ret
);
...
...
@@ -740,8 +742,7 @@ int SrsAvcAacCodec::avc_demux_sps_pps(SrsStream* stream)
if
(
sequenceParameterSetLength
>
0
)
{
srs_freep
(
sequenceParameterSetNALUnit
);
sequenceParameterSetNALUnit
=
new
char
[
sequenceParameterSetLength
];
memcpy
(
sequenceParameterSetNALUnit
,
stream
->
data
()
+
stream
->
pos
(),
sequenceParameterSetLength
);
stream
->
skip
(
sequenceParameterSetLength
);
stream
->
read_bytes
(
sequenceParameterSetNALUnit
,
sequenceParameterSetLength
);
}
// 1 pps
if
(
!
stream
->
require
(
1
))
{
...
...
@@ -770,10 +771,242 @@ int SrsAvcAacCodec::avc_demux_sps_pps(SrsStream* stream)
if
(
pictureParameterSetLength
>
0
)
{
srs_freep
(
pictureParameterSetNALUnit
);
pictureParameterSetNALUnit
=
new
char
[
pictureParameterSetLength
];
memcpy
(
pictureParameterSetNALUnit
,
stream
->
data
()
+
stream
->
pos
(),
pictureParameterSetLength
);
stream
->
skip
(
pictureParameterSetLength
);
stream
->
read_bytes
(
pictureParameterSetNALUnit
,
pictureParameterSetLength
);
}
return
avc_demux_sps
();
}
int
SrsAvcAacCodec
::
avc_demux_sps
()
{
int
ret
=
ERROR_SUCCESS
;
if
(
!
sequenceParameterSetLength
)
{
return
ret
;
}
SrsStream
stream
;
if
((
ret
=
stream
.
initialize
(
sequenceParameterSetNALUnit
,
sequenceParameterSetLength
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// for NALU, 7.3.1 NAL unit syntax
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
if
(
!
stream
.
require
(
1
))
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"avc decode sps failed. ret=%d"
,
ret
);
return
ret
;
}
int8_t
nutv
=
stream
.
read_1bytes
();
// forbidden_zero_bit shall be equal to 0.
int8_t
forbidden_zero_bit
=
(
nutv
>>
7
)
&
0x01
;
if
(
forbidden_zero_bit
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"forbidden_zero_bit shall be equal to 0. ret=%d"
,
ret
);
return
ret
;
}
// nal_ref_idc not equal to 0 specifies that the content of the NAL unit contains a sequence parameter set or a picture
// parameter set or a slice of a reference picture or a slice data partition of a reference picture.
int8_t
nal_ref_idc
=
(
nutv
>>
5
)
&
0x03
;
if
(
!
nal_ref_idc
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"for sps, nal_ref_idc shall be not be equal to 0. ret=%d"
,
ret
);
return
ret
;
}
// nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1.
// VCL NAL units are specified as those NAL units having nal_unit_type equal to 1, 2, 3, 4, 5, or 12.
// All remaining NAL units are called non-VCL NAL units.
int8_t
nal_unit_type
=
nutv
&
0x1f
;
if
(
nal_unit_type
!=
7
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"for sps, nal_unit_type shall be equal to 7. ret=%d"
,
ret
);
return
ret
;
}
// decode the rbsp from sps.
// rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes.
int8_t
*
rbsp
=
new
int8_t
[
sequenceParameterSetLength
];
SrsAutoFree
(
int8_t
,
rbsp
);
int
nb_rbsp
=
0
;
while
(
!
stream
.
empty
())
{
rbsp
[
nb_rbsp
]
=
stream
.
read_1bytes
();
// XX 00 00 03 XX, the 03 byte should be drop.
if
(
nb_rbsp
>
2
&&
rbsp
[
nb_rbsp
-
2
]
==
0
&&
rbsp
[
nb_rbsp
-
1
]
==
0
&&
rbsp
[
nb_rbsp
]
==
3
)
{
continue
;
}
nb_rbsp
++
;
}
return
avc_demux_sps_rbsp
((
char
*
)
rbsp
,
nb_rbsp
);
}
int
SrsAvcAacCodec
::
avc_demux_sps_rbsp
(
char
*
rbsp
,
int
nb_rbsp
)
{
int
ret
=
ERROR_SUCCESS
;
// reparse the rbsp.
SrsStream
stream
;
if
((
ret
=
stream
.
initialize
(
rbsp
,
nb_rbsp
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// for SPS, 7.3.2.1.1 Sequence parameter set data syntax
// H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 62.
if
(
!
stream
.
require
(
3
))
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"sps shall atleast 3bytes. ret=%d"
,
ret
);
return
ret
;
}
u_int8_t
profile_idc
=
stream
.
read_1bytes
();
if
(
!
profile_idc
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"sps the profile_idc invalid. ret=%d"
,
ret
);
return
ret
;
}
int8_t
flags
=
stream
.
read_1bytes
();
if
(
flags
&
0x03
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"sps the flags invalid. ret=%d"
,
ret
);
return
ret
;
}
u_int8_t
level_idc
=
stream
.
read_1bytes
();
if
(
!
level_idc
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"sps the level_idc invalid. ret=%d"
,
ret
);
return
ret
;
}
SrsBitStream
bs
;
if
((
ret
=
bs
.
initialize
(
&
stream
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int64_t
seq_parameter_set_id
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
seq_parameter_set_id
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
seq_parameter_set_id
<
0
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"sps the seq_parameter_set_id invalid. ret=%d"
,
ret
);
return
ret
;
}
srs_info
(
"sps parse profile=%d, level=%d, sps_id=%d"
,
profile_idc
,
level_idc
,
seq_parameter_set_id
);
if
(
profile_idc
==
100
||
profile_idc
==
110
||
profile_idc
==
122
||
profile_idc
==
244
||
profile_idc
==
44
||
profile_idc
==
83
||
profile_idc
==
86
||
profile_idc
==
118
||
profile_idc
==
128
)
{
int64_t
chroma_format_idc
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
chroma_format_idc
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
chroma_format_idc
==
3
)
{
int8_t
separate_colour_plane_flag
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_bit
(
&
bs
,
separate_colour_plane_flag
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
int64_t
bit_depth_luma_minus8
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
bit_depth_luma_minus8
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int64_t
bit_depth_chroma_minus8
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
bit_depth_chroma_minus8
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int8_t
qpprime_y_zero_transform_bypass_flag
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_bit
(
&
bs
,
qpprime_y_zero_transform_bypass_flag
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int8_t
seq_scaling_matrix_present_flag
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_bit
(
&
bs
,
seq_scaling_matrix_present_flag
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
seq_scaling_matrix_present_flag
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"sps the seq_scaling_matrix_present_flag invalid. ret=%d"
,
ret
);
return
ret
;
}
}
int64_t
log2_max_frame_num_minus4
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
log2_max_frame_num_minus4
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int64_t
pic_order_cnt_type
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
pic_order_cnt_type
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
pic_order_cnt_type
==
0
)
{
int64_t
log2_max_pic_order_cnt_lsb_minus4
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
log2_max_pic_order_cnt_lsb_minus4
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
else
if
(
pic_order_cnt_type
==
1
)
{
int8_t
delta_pic_order_always_zero_flag
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_bit
(
&
bs
,
delta_pic_order_always_zero_flag
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int64_t
offset_for_non_ref_pic
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
offset_for_non_ref_pic
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int64_t
offset_for_top_to_bottom_field
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
offset_for_top_to_bottom_field
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int64_t
num_ref_frames_in_pic_order_cnt_cycle
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
num_ref_frames_in_pic_order_cnt_cycle
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
num_ref_frames_in_pic_order_cnt_cycle
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"sps the num_ref_frames_in_pic_order_cnt_cycle invalid. ret=%d"
,
ret
);
return
ret
;
}
}
int64_t
max_num_ref_frames
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
max_num_ref_frames
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int8_t
gaps_in_frame_num_value_allowed_flag
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_bit
(
&
bs
,
gaps_in_frame_num_value_allowed_flag
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int64_t
pic_width_in_mbs_minus1
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
pic_width_in_mbs_minus1
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int64_t
pic_height_in_map_units_minus1
=
-
1
;
if
((
ret
=
srs_avc_nalu_read_uev
(
&
bs
,
pic_height_in_map_units_minus1
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
width
=
(
int
)(
pic_width_in_mbs_minus1
+
1
)
*
16
;
height
=
(
int
)(
pic_height_in_map_units_minus1
+
1
)
*
16
;
return
ret
;
}
...
...
trunk/src/kernel/srs_kernel_codec.hpp
查看文件 @
70c59da
...
...
@@ -581,6 +581,11 @@ private:
*/
virtual
int
avc_demux_sps_pps
(
SrsStream
*
stream
);
/**
* decode the sps rbsp stream.
*/
virtual
int
avc_demux_sps
();
virtual
int
avc_demux_sps_rbsp
(
char
*
rbsp
,
int
nb_rbsp
);
/**
* demux the avc NALU in "AnnexB"
* from H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
*/
...
...
trunk/src/kernel/srs_kernel_error.hpp
查看文件 @
70c59da
...
...
@@ -215,7 +215,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_HTTP_DVR_CREATE_REQUEST 3053
#define ERROR_HTTP_DVR_NO_TAEGET 3054
#define ERROR_ADTS_ID_NOT_AAC 3055
// HDS error code
#define ERROR_HDS_OPEN_F4M_FAILED 3056
#define ERROR_HDS_WRITE_F4M_FAILED 3057
...
...
@@ -254,6 +253,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_STREAM_CASTER_FLV_TAG 4024
#define ERROR_HTTP_RESPONSE_EOF 4025
#define ERROR_HTTP_INVALID_CHUNK_HEADER 4026
#define ERROR_AVC_NALU_UEV 4027
///////////////////////////////////////////////////////
// user-define error.
...
...
trunk/src/kernel/srs_kernel_stream.cpp
查看文件 @
70c59da
...
...
@@ -252,4 +252,38 @@ void SrsStream::write_bytes(char* data, int size)
p
+=
size
;
}
SrsBitStream
::
SrsBitStream
()
{
cb
=
0
;
cb_left
=
0
;
stream
=
NULL
;
}
SrsBitStream
::~
SrsBitStream
()
{
}
int
SrsBitStream
::
initialize
(
SrsStream
*
s
)
{
stream
=
s
;
return
ERROR_SUCCESS
;
}
bool
SrsBitStream
::
empty
()
{
if
(
cb_left
)
{
return
false
;
}
return
stream
->
empty
();
}
int8_t
SrsBitStream
::
read_bit
()
{
if
(
!
cb_left
)
{
srs_assert
(
!
stream
->
empty
());
cb
=
stream
->
read_1bytes
();
cb_left
=
8
;
}
int8_t
v
=
(
cb
>>
(
cb_left
-
1
))
&
0x01
;
cb_left
--
;
return
v
;
}
...
...
trunk/src/kernel/srs_kernel_stream.hpp
查看文件 @
70c59da
...
...
@@ -154,4 +154,22 @@ public:
virtual
void
write_bytes
(
char
*
data
,
int
size
);
};
/**
* the bit stream.
*/
class
SrsBitStream
{
private
:
int8_t
cb
;
u_int8_t
cb_left
;
SrsStream
*
stream
;
public
:
SrsBitStream
();
virtual
~
SrsBitStream
();
public
:
virtual
int
initialize
(
SrsStream
*
s
);
virtual
bool
empty
();
virtual
int8_t
read_bit
();
};
#endif
...
...
trunk/src/kernel/srs_kernel_utility.cpp
查看文件 @
70c59da
...
...
@@ -46,6 +46,53 @@ using namespace std;
// @see SRS_SYS_TIME_RESOLUTION_MS_TIMES
#define SYS_TIME_RESOLUTION_US 300*1000
int
srs_avc_nalu_read_uev
(
SrsBitStream
*
stream
,
int64_t
&
v
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
stream
->
empty
())
{
return
ERROR_AVC_NALU_UEV
;
}
// ue(v) in 9.1 Parsing process for Exp-Golomb codes
// H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 227.
// Syntax elements coded as ue(v), me(v), or se(v) are Exp-Golomb-coded.
// leadingZeroBits = -1;
// for( b = 0; !b; leadingZeroBits++ )
// b = read_bits( 1 )
// The variable codeNum is then assigned as follows:
// codeNum = (2<<leadingZeroBits) – 1 + read_bits( leadingZeroBits )
int
leadingZeroBits
=
-
1
;
for
(
int8_t
b
=
0
;
!
b
&&
!
stream
->
empty
();
leadingZeroBits
++
)
{
b
=
stream
->
read_bit
();
}
if
(
leadingZeroBits
>=
64
)
{
return
ERROR_AVC_NALU_UEV
;
}
v
=
(
1
<<
leadingZeroBits
)
-
1
;
for
(
int
i
=
0
;
i
<
leadingZeroBits
;
i
++
)
{
int64_t
b
=
stream
->
read_bit
();
v
+=
b
<<
(
leadingZeroBits
-
1
);
}
return
ret
;
}
int
srs_avc_nalu_read_bit
(
SrsBitStream
*
stream
,
int8_t
&
v
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
stream
->
empty
())
{
return
ERROR_AVC_NALU_UEV
;
}
v
=
stream
->
read_bit
();
return
ret
;
}
static
int64_t
_srs_system_time_us_cache
=
0
;
static
int64_t
_srs_system_time_startup_time
=
0
;
...
...
trunk/src/kernel/srs_kernel_utility.hpp
查看文件 @
70c59da
...
...
@@ -33,11 +33,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <string>
class
SrsStream
;
class
SrsBitStream
;
// compare
#define srs_min(a, b) (((a) < (b))? (a) : (b))
#define srs_max(a, b) (((a) < (b))? (b) : (a))
// read nalu uev.
extern
int
srs_avc_nalu_read_uev
(
SrsBitStream
*
stream
,
int64_t
&
v
);
extern
int
srs_avc_nalu_read_bit
(
SrsBitStream
*
stream
,
int8_t
&
v
);
// get current system time in ms, use cache to avoid performance problem
extern
int64_t
srs_get_system_time_ms
();
extern
int64_t
srs_get_system_startup_time_ms
();
...
...
请
注册
或
登录
后发表评论