Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
dd80d6a6
Commit
dd80d6a6
authored
Aug 02, 2019
by
xiongziliang
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' of
https://github.com/zqsong/ZLMediaKit
into zqsong
parents
1f890198
0d57664f
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
762 行增加
和
639 行删除
+762
-639
src/Extension/H265.cpp
+29
-13
src/Extension/H265.h
+3
-3
src/Extension/SPSParser.c
+568
-483
src/Extension/SPSParser.h
+162
-140
没有找到文件。
src/Extension/H265.cpp
查看文件 @
dd80d6a6
...
@@ -32,24 +32,40 @@ namespace mediakit{
...
@@ -32,24 +32,40 @@ namespace mediakit{
bool
getAVCH265Info
(
const
string
&
strSps
,
int
&
iVideoWidth
,
int
&
iVideoHeight
,
float
&
iVideoFps
)
{
bool
getAVCH265Info
(
const
string
&
str
Vps
,
const
string
&
str
Sps
,
int
&
iVideoWidth
,
int
&
iVideoHeight
,
float
&
iVideoFps
)
{
return
getAVC265Info
(
strSps
.
data
(),
strSps
.
size
(),
iVideoWidth
,
iVideoHeight
,
iVideoFps
);
return
getAVC265Info
(
str
Vps
.
data
(),
strVps
.
size
(),
str
Sps
.
data
(),
strSps
.
size
(),
iVideoWidth
,
iVideoHeight
,
iVideoFps
);
}
}
bool
getAVC265Info
(
const
char
*
sps
,
int
sps_len
,
int
&
iVideoWidth
,
int
&
iVideoHeight
,
float
&
iVideoFps
){
bool
getAVC265Info
(
const
char
*
vps
,
int
vps_len
,
const
char
*
sps
,
int
sps_len
,
int
&
iVideoWidth
,
int
&
iVideoHeight
,
float
&
iVideoFps
){
T_GetBitContext
tGetBitBuf
;
T_GetBitContext
tGetBitBuf
;
T_HEVCSPS
tH265SpsInfo
;
T_HEVCSPS
tH265SpsInfo
;
memset
(
&
tGetBitBuf
,
0
,
sizeof
(
tGetBitBuf
));
T_HEVCVPS
tH265VpsInfo
;
memset
(
&
tH265SpsInfo
,
0
,
sizeof
(
tH265SpsInfo
));
if
(
vps_len
>
2
){
tGetBitBuf
.
pu8Buf
=
(
uint8_t
*
)
sps
;
memset
(
&
tGetBitBuf
,
0
,
sizeof
(
tGetBitBuf
));
tGetBitBuf
.
iBufSize
=
sps_len
;
memset
(
&
tH265VpsInfo
,
0
,
sizeof
(
tH265VpsInfo
));
if
(
0
!=
h265DecSeqParameterSet
((
void
*
)
&
tGetBitBuf
,
&
tH265SpsInfo
)){
tGetBitBuf
.
pu8Buf
=
(
uint8_t
*
)
vps
+
2
;
return
false
;
tGetBitBuf
.
iBufSize
=
vps_len
-
2
;
}
if
(
0
!=
h265DecVideoParameterSet
((
void
*
)
&
tGetBitBuf
,
&
tH265VpsInfo
)){
return
false
;
}
}
if
(
sps_len
>
2
){
memset
(
&
tGetBitBuf
,
0
,
sizeof
(
tGetBitBuf
));
memset
(
&
tH265SpsInfo
,
0
,
sizeof
(
tH265SpsInfo
));
tGetBitBuf
.
pu8Buf
=
(
uint8_t
*
)
sps
+
2
;
tGetBitBuf
.
iBufSize
=
sps_len
-
2
;
if
(
0
!=
h265DecSeqParameterSet
((
void
*
)
&
tGetBitBuf
,
&
tH265SpsInfo
)){
return
false
;
}
}
else
return
false
;
h265GetWidthHeight
(
&
tH265SpsInfo
,
&
iVideoWidth
,
&
iVideoHeight
);
h265GetWidthHeight
(
&
tH265SpsInfo
,
&
iVideoWidth
,
&
iVideoHeight
);
h265GeFramerate
(
&
tH265SpsInfo
,
&
iVideoFps
);
iVideoFps
=
0
;
//ErrorL << iVideoWidth << " " << iVideoHeight << " " << iVideoFps;
h265GeFramerate
(
&
tH265VpsInfo
,
&
tH265SpsInfo
,
&
iVideoFps
);
// ErrorL << iVideoWidth << " " << iVideoHeight << " " << iVideoFps;
return
true
;
return
true
;
}
}
...
...
src/Extension/H265.h
查看文件 @
dd80d6a6
...
@@ -36,8 +36,8 @@ using namespace toolkit;
...
@@ -36,8 +36,8 @@ using namespace toolkit;
namespace
mediakit
{
namespace
mediakit
{
bool
getAVCH265Info
(
const
string
&
strSps
,
int
&
iVideoWidth
,
int
&
iVideoHeight
,
float
&
iVideoFps
);
bool
getAVCH265Info
(
const
string
&
str
Vps
,
const
string
&
str
Sps
,
int
&
iVideoWidth
,
int
&
iVideoHeight
,
float
&
iVideoFps
);
bool
getAVC265Info
(
const
char
*
sps
,
int
sps_len
,
int
&
iVideoWidth
,
int
&
iVideoHeight
,
float
&
iVideoFps
);
bool
getAVC265Info
(
const
char
*
vps
,
int
vps_len
,
const
char
*
sps
,
int
sps_len
,
int
&
iVideoWidth
,
int
&
iVideoHeight
,
float
&
iVideoFps
);
/**
/**
* 265帧类
* 265帧类
...
@@ -336,7 +336,7 @@ private:
...
@@ -336,7 +336,7 @@ private:
* 解析sps获取宽高fps
* 解析sps获取宽高fps
*/
*/
void
onReady
(){
void
onReady
(){
getAVCH265Info
(
_sps
,
_width
,
_height
,
_fps
);
getAVCH265Info
(
_
vps
,
_
sps
,
_width
,
_height
,
_fps
);
}
}
Track
::
Ptr
clone
()
override
{
Track
::
Ptr
clone
()
override
{
return
std
::
make_shared
<
std
::
remove_reference
<
decltype
(
*
this
)
>::
type
>
(
*
this
);
return
std
::
make_shared
<
std
::
remove_reference
<
decltype
(
*
this
)
>::
type
>
(
*
this
);
...
...
src/Extension/SPSParser.c
查看文件 @
dd80d6a6
...
@@ -129,15 +129,15 @@ const uint8_t g_au8FfZigzagDirect[64] = {
...
@@ -129,15 +129,15 @@ const uint8_t g_au8FfZigzagDirect[64] = {
};
};
static
const
uint8_t
hevc_sub_width_c
[]
=
{
static
const
uint8_t
sg_au8HevcSubWidthC
[]
=
{
1
,
2
,
2
,
1
1
,
2
,
2
,
1
};
};
static
const
uint8_t
hevc_sub_height_c
[]
=
{
static
const
uint8_t
sg_au8HevcSubHeightC
[]
=
{
1
,
2
,
1
,
1
1
,
2
,
1
,
1
};
};
static
const
uint8_t
default_scaling_list_i
ntra
[]
=
{
static
const
uint8_t
sg_au8DefaultScalingListI
ntra
[]
=
{
16
,
16
,
16
,
16
,
17
,
18
,
21
,
24
,
16
,
16
,
16
,
16
,
17
,
18
,
21
,
24
,
16
,
16
,
16
,
16
,
17
,
19
,
22
,
25
,
16
,
16
,
16
,
16
,
17
,
19
,
22
,
25
,
16
,
16
,
17
,
18
,
20
,
22
,
25
,
29
,
16
,
16
,
17
,
18
,
20
,
22
,
25
,
29
,
...
@@ -148,7 +148,7 @@ static const uint8_t default_scaling_list_intra[] = {
...
@@ -148,7 +148,7 @@ static const uint8_t default_scaling_list_intra[] = {
24
,
25
,
29
,
36
,
47
,
65
,
88
,
115
24
,
25
,
29
,
36
,
47
,
65
,
88
,
115
};
};
static
const
uint8_t
default_scaling_list_i
nter
[]
=
{
static
const
uint8_t
sg_au8DefaultScalingListI
nter
[]
=
{
16
,
16
,
16
,
16
,
17
,
18
,
20
,
24
,
16
,
16
,
16
,
16
,
17
,
18
,
20
,
24
,
16
,
16
,
16
,
17
,
18
,
20
,
24
,
25
,
16
,
16
,
16
,
17
,
18
,
20
,
24
,
25
,
16
,
16
,
17
,
18
,
20
,
24
,
25
,
28
,
16
,
16
,
17
,
18
,
20
,
24
,
25
,
28
,
...
@@ -160,21 +160,21 @@ static const uint8_t default_scaling_list_inter[] = {
...
@@ -160,21 +160,21 @@ static const uint8_t default_scaling_list_inter[] = {
};
};
const
uint8_t
ff_hevc_diag_scan4x4_x
[
16
]
=
{
const
uint8_t
g_au8HevcDiagScan4x4X
[
16
]
=
{
0
,
0
,
1
,
0
,
0
,
0
,
1
,
0
,
1
,
2
,
0
,
1
,
1
,
2
,
0
,
1
,
2
,
3
,
1
,
2
,
2
,
3
,
1
,
2
,
3
,
2
,
3
,
3
,
3
,
2
,
3
,
3
,
};
};
const
uint8_t
ff_hevc_diag_scan4x4_y
[
16
]
=
{
const
uint8_t
g_au8HevcDiagScan4x4Y
[
16
]
=
{
0
,
1
,
0
,
2
,
0
,
1
,
0
,
2
,
1
,
0
,
3
,
2
,
1
,
0
,
3
,
2
,
1
,
0
,
3
,
2
,
1
,
0
,
3
,
2
,
1
,
3
,
2
,
3
,
1
,
3
,
2
,
3
,
};
};
const
uint8_t
ff_hevc_diag_scan8x8_x
[
64
]
=
{
const
uint8_t
g_au8HevcDiagScan8x8X
[
64
]
=
{
0
,
0
,
1
,
0
,
0
,
0
,
1
,
0
,
1
,
2
,
0
,
1
,
1
,
2
,
0
,
1
,
2
,
3
,
0
,
1
,
2
,
3
,
0
,
1
,
...
@@ -193,7 +193,7 @@ const uint8_t ff_hevc_diag_scan8x8_x[64] = {
...
@@ -193,7 +193,7 @@ const uint8_t ff_hevc_diag_scan8x8_x[64] = {
7
,
6
,
7
,
7
,
7
,
6
,
7
,
7
,
};
};
const
uint8_t
ff_hevc_diag_scan8x8_y
[
64
]
=
{
const
uint8_t
g_au8HevcDiagScan8x8Y
[
64
]
=
{
0
,
1
,
0
,
2
,
0
,
1
,
0
,
2
,
1
,
0
,
3
,
2
,
1
,
0
,
3
,
2
,
1
,
0
,
4
,
3
,
1
,
0
,
4
,
3
,
...
@@ -212,7 +212,7 @@ const uint8_t ff_hevc_diag_scan8x8_y[64] = {
...
@@ -212,7 +212,7 @@ const uint8_t ff_hevc_diag_scan8x8_y[64] = {
5
,
7
,
6
,
7
,
5
,
7
,
6
,
7
,
};
};
static
const
T_AVRational
vui_s
ar
[]
=
{
static
const
T_AVRational
sg_atVuiS
ar
[]
=
{
{
0
,
1
},
{
0
,
1
},
{
1
,
1
},
{
1
,
1
},
{
12
,
11
},
{
12
,
11
},
...
@@ -733,17 +733,17 @@ static inline int decodeVuiParameters(void *pvBuf, T_SPS *ptSps)
...
@@ -733,17 +733,17 @@ static inline int decodeVuiParameters(void *pvBuf, T_SPS *ptSps)
ptSps
->
tSar
.
den
=
0
;
ptSps
->
tSar
.
den
=
0
;
}
}
if
(
getOneBit
(
pvBuf
))
/*
overscan_info_present_f
lag */
if
(
getOneBit
(
pvBuf
))
/*
iOverscanInfoPresentF
lag */
getOneBit
(
pvBuf
);
/*
overscan_appropriate_f
lag */
getOneBit
(
pvBuf
);
/*
iOverscanAppropriateF
lag */
ptSps
->
iVideoSignalTypePresentFlag
=
getOneBit
(
pvBuf
);
ptSps
->
iVideoSignalTypePresentFlag
=
getOneBit
(
pvBuf
);
if
(
ptSps
->
iVideoSignalTypePresentFlag
)
{
if
(
ptSps
->
iVideoSignalTypePresentFlag
)
{
getBits
(
pvBuf
,
3
);
/* video_format */
getBits
(
pvBuf
,
3
);
/* video_format */
ptSps
->
iFullRange
=
getOneBit
(
pvBuf
);
/*
video_full_range_f
lag */
ptSps
->
iFullRange
=
getOneBit
(
pvBuf
);
/*
iVideoFullRangeF
lag */
ptSps
->
iColourDescriptionPresentFlag
=
getOneBit
(
pvBuf
);
ptSps
->
iColourDescriptionPresentFlag
=
getOneBit
(
pvBuf
);
if
(
ptSps
->
iColourDescriptionPresentFlag
)
{
if
(
ptSps
->
iColourDescriptionPresentFlag
)
{
ptSps
->
tColorPrimaries
=
getBits
(
pvBuf
,
8
);
/*
colour_p
rimaries */
ptSps
->
tColorPrimaries
=
getBits
(
pvBuf
,
8
);
/*
u8ColourP
rimaries */
ptSps
->
tColorTrc
=
getBits
(
pvBuf
,
8
);
/* transfer_characteristics */
ptSps
->
tColorTrc
=
getBits
(
pvBuf
,
8
);
/* transfer_characteristics */
ptSps
->
tColorspace
=
getBits
(
pvBuf
,
8
);
/* matrix_coefficients */
ptSps
->
tColorspace
=
getBits
(
pvBuf
,
8
);
/* matrix_coefficients */
if
(
ptSps
->
tColorPrimaries
>=
AVCOL_PRI_NB
)
if
(
ptSps
->
tColorPrimaries
>=
AVCOL_PRI_NB
)
...
@@ -800,7 +800,7 @@ static inline int decodeVuiParameters(void *pvBuf, T_SPS *ptSps)
...
@@ -800,7 +800,7 @@ static inline int decodeVuiParameters(void *pvBuf, T_SPS *ptSps)
return
0
;
return
0
;
ptSps
->
iBitstreamRestrictionFlag
=
getOneBit
(
pvBuf
);
ptSps
->
iBitstreamRestrictionFlag
=
getOneBit
(
pvBuf
);
if
(
ptSps
->
iBitstreamRestrictionFlag
)
{
if
(
ptSps
->
iBitstreamRestrictionFlag
)
{
getOneBit
(
pvBuf
);
/* motion_vectors_over_pic_boundaries_flag */
getOneBit
(
pvBuf
);
/* motion_vectors_over_pic_boundaries_flag */
parseUe
(
pvBuf
);
parseUe
(
pvBuf
);
//get_ue_golomb(&h->gb); /* max_bytes_per_pic_denom */
//get_ue_golomb(&h->gb); /* max_bytes_per_pic_denom */
parseUe
(
pvBuf
);
parseUe
(
pvBuf
);
...
@@ -1035,8 +1035,8 @@ int h264DecSeqParameterSet(void *pvBufSrc, T_SPS *ptSps)
...
@@ -1035,8 +1035,8 @@ int h264DecSeqParameterSet(void *pvBufSrc, T_SPS *ptSps)
unsigned
int
uiCropRight
=
parseUe
(
pvBuf
);
unsigned
int
uiCropRight
=
parseUe
(
pvBuf
);
unsigned
int
uiCropTop
=
parseUe
(
pvBuf
);
unsigned
int
uiCropTop
=
parseUe
(
pvBuf
);
unsigned
int
uiCropBottom
=
parseUe
(
pvBuf
);
unsigned
int
uiCropBottom
=
parseUe
(
pvBuf
);
int
w
idth
=
16
*
ptSps
->
iMbWidth
;
int
iW
idth
=
16
*
ptSps
->
iMbWidth
;
int
h
eight
=
16
*
ptSps
->
iMbHeight
*
(
2
-
ptSps
->
iFrameMbsOnlyFlag
);
int
iH
eight
=
16
*
ptSps
->
iMbHeight
*
(
2
-
ptSps
->
iFrameMbsOnlyFlag
);
if
(
1
)
if
(
1
)
{
{
...
@@ -1055,11 +1055,11 @@ int h264DecSeqParameterSet(void *pvBufSrc, T_SPS *ptSps)
...
@@ -1055,11 +1055,11 @@ int h264DecSeqParameterSet(void *pvBufSrc, T_SPS *ptSps)
uiCropRight
>
(
unsigned
)
INT_MAX
/
4
/
step_x
||
uiCropRight
>
(
unsigned
)
INT_MAX
/
4
/
step_x
||
uiCropTop
>
(
unsigned
)
INT_MAX
/
4
/
step_y
||
uiCropTop
>
(
unsigned
)
INT_MAX
/
4
/
step_y
||
uiCropBottom
>
(
unsigned
)
INT_MAX
/
4
/
step_y
||
uiCropBottom
>
(
unsigned
)
INT_MAX
/
4
/
step_y
||
(
uiCropLeft
+
uiCropRight
)
*
step_x
>=
w
idth
||
(
uiCropLeft
+
uiCropRight
)
*
step_x
>=
iW
idth
||
(
uiCropTop
+
uiCropBottom
)
*
step_y
>=
h
eight
(
uiCropTop
+
uiCropBottom
)
*
step_y
>=
iH
eight
)
)
{
{
RPT
(
RPT_ERR
,
"crop values invalid %d %d %d %d / %d %d
\n
"
,
uiCropLeft
,
uiCropRight
,
uiCropTop
,
uiCropBottom
,
width
,
h
eight
);
RPT
(
RPT_ERR
,
"crop values invalid %d %d %d %d / %d %d
\n
"
,
uiCropLeft
,
uiCropRight
,
uiCropTop
,
uiCropBottom
,
iWidth
,
iH
eight
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
...
@@ -1129,37 +1129,37 @@ exit:
...
@@ -1129,37 +1129,37 @@ exit:
}
}
static
int
decodeProfileTierLevel
(
T_GetBitContext
*
pvBuf
,
T_PTLCommon
*
p
tl
)
static
int
decodeProfileTierLevel
(
T_GetBitContext
*
pvBuf
,
T_PTLCommon
*
tP
tl
)
{
{
int
i
;
int
i
;
if
(
getBitsLeft
(
pvBuf
)
<
2
+
1
+
5
+
32
+
4
+
16
+
16
+
12
)
if
(
getBitsLeft
(
pvBuf
)
<
2
+
1
+
5
+
32
+
4
+
16
+
16
+
12
)
return
-
1
;
return
-
1
;
ptl
->
profile_s
pace
=
getBits
(
pvBuf
,
2
);
tPtl
->
u8ProfileS
pace
=
getBits
(
pvBuf
,
2
);
ptl
->
tier_f
lag
=
getOneBit
(
pvBuf
);
tPtl
->
u8TierF
lag
=
getOneBit
(
pvBuf
);
ptl
->
profile_i
dc
=
getBits
(
pvBuf
,
5
);
tPtl
->
u8ProfileI
dc
=
getBits
(
pvBuf
,
5
);
if
(
ptl
->
profile_i
dc
==
T_PROFILE_HEVC_MAIN
)
if
(
tPtl
->
u8ProfileI
dc
==
T_PROFILE_HEVC_MAIN
)
RPT
(
RPT_DBG
,
"Main profile bitstream
\n
"
);
RPT
(
RPT_DBG
,
"Main profile bitstream
\n
"
);
else
if
(
ptl
->
profile_i
dc
==
T_PROFILE_HEVC_MAIN_10
)
else
if
(
tPtl
->
u8ProfileI
dc
==
T_PROFILE_HEVC_MAIN_10
)
RPT
(
RPT_DBG
,
"Main 10 profile bitstream
\n
"
);
RPT
(
RPT_DBG
,
"Main 10 profile bitstream
\n
"
);
else
if
(
ptl
->
profile_i
dc
==
T_PROFILE_HEVC_MAIN_STILL_PICTURE
)
else
if
(
tPtl
->
u8ProfileI
dc
==
T_PROFILE_HEVC_MAIN_STILL_PICTURE
)
RPT
(
RPT_DBG
,
"Main Still Picture profile bitstream
\n
"
);
RPT
(
RPT_DBG
,
"Main Still Picture profile bitstream
\n
"
);
else
if
(
ptl
->
profile_i
dc
==
T_PROFILE_HEVC_REXT
)
else
if
(
tPtl
->
u8ProfileI
dc
==
T_PROFILE_HEVC_REXT
)
RPT
(
RPT_DBG
,
"Range Extension profile bitstream
\n
"
);
RPT
(
RPT_DBG
,
"Range Extension profile bitstream
\n
"
);
else
else
RPT
(
RPT_WRN
,
"Unknown HEVC profile: %d
\n
"
,
ptl
->
profile_i
dc
);
RPT
(
RPT_WRN
,
"Unknown HEVC profile: %d
\n
"
,
tPtl
->
u8ProfileI
dc
);
for
(
i
=
0
;
i
<
32
;
i
++
)
{
for
(
i
=
0
;
i
<
32
;
i
++
)
{
ptl
->
profile_compatibility_f
lag
[
i
]
=
getOneBit
(
pvBuf
);
tPtl
->
au8ProfileCompatibilityF
lag
[
i
]
=
getOneBit
(
pvBuf
);
if
(
ptl
->
profile_idc
==
0
&&
i
>
0
&&
ptl
->
profile_compatibility_f
lag
[
i
])
if
(
tPtl
->
u8ProfileIdc
==
0
&&
i
>
0
&&
tPtl
->
au8ProfileCompatibilityF
lag
[
i
])
ptl
->
profile_i
dc
=
i
;
tPtl
->
u8ProfileI
dc
=
i
;
}
}
ptl
->
progressive_source_f
lag
=
getOneBit
(
pvBuf
);
tPtl
->
u8ProgressiveSourceF
lag
=
getOneBit
(
pvBuf
);
ptl
->
interlaced_source_f
lag
=
getOneBit
(
pvBuf
);
tPtl
->
u8InterlacedSourceF
lag
=
getOneBit
(
pvBuf
);
ptl
->
non_packed_constraint_flag
=
getOneBit
(
pvBuf
);
tPtl
->
u8NonPackedConstraintFlag
=
getOneBit
(
pvBuf
);
ptl
->
frame_only_constraint_flag
=
getOneBit
(
pvBuf
);
tPtl
->
u8FrameOnlyConstraintFlag
=
getOneBit
(
pvBuf
);
getBits
(
pvBuf
,
16
);
// XXX_reserved_zero_44bits[0..15]
getBits
(
pvBuf
,
16
);
// XXX_reserved_zero_44bits[0..15]
getBits
(
pvBuf
,
16
);
// XXX_reserved_zero_44bits[16..31]
getBits
(
pvBuf
,
16
);
// XXX_reserved_zero_44bits[16..31]
...
@@ -1169,39 +1169,39 @@ static int decodeProfileTierLevel(T_GetBitContext *pvBuf, T_PTLCommon *ptl)
...
@@ -1169,39 +1169,39 @@ static int decodeProfileTierLevel(T_GetBitContext *pvBuf, T_PTLCommon *ptl)
}
}
static
int
parsePtl
(
T_GetBitContext
*
pvBuf
,
T_PTL
*
p
tl
,
int
max_num_sub_layers
)
static
int
parsePtl
(
T_GetBitContext
*
pvBuf
,
T_PTL
*
tP
tl
,
int
max_num_sub_layers
)
{
{
int
i
;
int
i
;
if
(
decodeProfileTierLevel
(
pvBuf
,
&
ptl
->
general_p
tl
)
<
0
||
if
(
decodeProfileTierLevel
(
pvBuf
,
&
tPtl
->
tGeneralP
tl
)
<
0
||
getBitsLeft
(
pvBuf
)
<
8
+
(
8
*
2
*
(
max_num_sub_layers
-
1
>
0
)))
{
getBitsLeft
(
pvBuf
)
<
8
+
(
8
*
2
*
(
max_num_sub_layers
-
1
>
0
)))
{
RPT
(
RPT_ERR
,
"PTL information too short
\n
"
);
RPT
(
RPT_ERR
,
"PTL information too short
\n
"
);
return
-
1
;
return
-
1
;
}
}
ptl
->
general_ptl
.
level_i
dc
=
getBits
(
pvBuf
,
8
);
tPtl
->
tGeneralPtl
.
u8LevelI
dc
=
getBits
(
pvBuf
,
8
);
for
(
i
=
0
;
i
<
max_num_sub_layers
-
1
;
i
++
)
{
for
(
i
=
0
;
i
<
max_num_sub_layers
-
1
;
i
++
)
{
ptl
->
sub_layer_profile_present_f
lag
[
i
]
=
getOneBit
(
pvBuf
);
tPtl
->
au8SubLayerProfilePresentF
lag
[
i
]
=
getOneBit
(
pvBuf
);
ptl
->
sub_layer_level_present_f
lag
[
i
]
=
getOneBit
(
pvBuf
);
tPtl
->
au8SubLayerLevelPresentF
lag
[
i
]
=
getOneBit
(
pvBuf
);
}
}
if
(
max_num_sub_layers
-
1
>
0
)
if
(
max_num_sub_layers
-
1
>
0
)
for
(
i
=
max_num_sub_layers
-
1
;
i
<
8
;
i
++
)
for
(
i
=
max_num_sub_layers
-
1
;
i
<
8
;
i
++
)
getBits
(
pvBuf
,
2
);
// reserved_zero_2bits[i]
getBits
(
pvBuf
,
2
);
// reserved_zero_2bits[i]
for
(
i
=
0
;
i
<
max_num_sub_layers
-
1
;
i
++
)
{
for
(
i
=
0
;
i
<
max_num_sub_layers
-
1
;
i
++
)
{
if
(
ptl
->
sub_layer_profile_present_f
lag
[
i
]
&&
if
(
tPtl
->
au8SubLayerProfilePresentF
lag
[
i
]
&&
decodeProfileTierLevel
(
pvBuf
,
&
ptl
->
sub_layer_p
tl
[
i
])
<
0
)
{
decodeProfileTierLevel
(
pvBuf
,
&
tPtl
->
atSubLayerP
tl
[
i
])
<
0
)
{
RPT
(
RPT_ERR
,
RPT
(
RPT_ERR
,
"PTL information for sublayer %i too short
\n
"
,
i
);
"PTL information for sublayer %i too short
\n
"
,
i
);
return
-
1
;
return
-
1
;
}
}
if
(
ptl
->
sub_layer_level_present_f
lag
[
i
])
{
if
(
tPtl
->
au8SubLayerLevelPresentF
lag
[
i
])
{
if
(
getBitsLeft
(
pvBuf
)
<
8
)
{
if
(
getBitsLeft
(
pvBuf
)
<
8
)
{
RPT
(
RPT_ERR
,
RPT
(
RPT_ERR
,
"Not enough data for sublayer %i level_idc
\n
"
,
i
);
"Not enough data for sublayer %i level_idc
\n
"
,
i
);
return
-
1
;
return
-
1
;
}
else
}
else
ptl
->
sub_layer_ptl
[
i
].
level_i
dc
=
getBits
(
pvBuf
,
8
);
tPtl
->
atSubLayerPtl
[
i
].
u8LevelI
dc
=
getBits
(
pvBuf
,
8
);
}
}
}
}
...
@@ -1215,31 +1215,31 @@ static void setDefaultScalingListData(T_ScalingList *sl)
...
@@ -1215,31 +1215,31 @@ static void setDefaultScalingListData(T_ScalingList *sl)
for
(
matrixId
=
0
;
matrixId
<
6
;
matrixId
++
)
{
for
(
matrixId
=
0
;
matrixId
<
6
;
matrixId
++
)
{
// 4x4 default is 16
// 4x4 default is 16
memset
(
sl
->
s
l
[
0
][
matrixId
],
16
,
16
);
memset
(
sl
->
aaau8S
l
[
0
][
matrixId
],
16
,
16
);
sl
->
sl_d
c
[
0
][
matrixId
]
=
16
;
// default for 16x16
sl
->
aau8SlD
c
[
0
][
matrixId
]
=
16
;
// default for 16x16
sl
->
sl_d
c
[
1
][
matrixId
]
=
16
;
// default for 32x32
sl
->
aau8SlD
c
[
1
][
matrixId
]
=
16
;
// default for 32x32
}
}
memcpy
(
sl
->
sl
[
1
][
0
],
default_scaling_list_i
ntra
,
64
);
memcpy
(
sl
->
aaau8Sl
[
1
][
0
],
sg_au8DefaultScalingListI
ntra
,
64
);
memcpy
(
sl
->
sl
[
1
][
1
],
default_scaling_list_i
ntra
,
64
);
memcpy
(
sl
->
aaau8Sl
[
1
][
1
],
sg_au8DefaultScalingListI
ntra
,
64
);
memcpy
(
sl
->
sl
[
1
][
2
],
default_scaling_list_i
ntra
,
64
);
memcpy
(
sl
->
aaau8Sl
[
1
][
2
],
sg_au8DefaultScalingListI
ntra
,
64
);
memcpy
(
sl
->
sl
[
1
][
3
],
default_scaling_list_i
nter
,
64
);
memcpy
(
sl
->
aaau8Sl
[
1
][
3
],
sg_au8DefaultScalingListI
nter
,
64
);
memcpy
(
sl
->
sl
[
1
][
4
],
default_scaling_list_i
nter
,
64
);
memcpy
(
sl
->
aaau8Sl
[
1
][
4
],
sg_au8DefaultScalingListI
nter
,
64
);
memcpy
(
sl
->
sl
[
1
][
5
],
default_scaling_list_i
nter
,
64
);
memcpy
(
sl
->
aaau8Sl
[
1
][
5
],
sg_au8DefaultScalingListI
nter
,
64
);
memcpy
(
sl
->
sl
[
2
][
0
],
default_scaling_list_i
ntra
,
64
);
memcpy
(
sl
->
aaau8Sl
[
2
][
0
],
sg_au8DefaultScalingListI
ntra
,
64
);
memcpy
(
sl
->
sl
[
2
][
1
],
default_scaling_list_i
ntra
,
64
);
memcpy
(
sl
->
aaau8Sl
[
2
][
1
],
sg_au8DefaultScalingListI
ntra
,
64
);
memcpy
(
sl
->
sl
[
2
][
2
],
default_scaling_list_i
ntra
,
64
);
memcpy
(
sl
->
aaau8Sl
[
2
][
2
],
sg_au8DefaultScalingListI
ntra
,
64
);
memcpy
(
sl
->
sl
[
2
][
3
],
default_scaling_list_i
nter
,
64
);
memcpy
(
sl
->
aaau8Sl
[
2
][
3
],
sg_au8DefaultScalingListI
nter
,
64
);
memcpy
(
sl
->
sl
[
2
][
4
],
default_scaling_list_i
nter
,
64
);
memcpy
(
sl
->
aaau8Sl
[
2
][
4
],
sg_au8DefaultScalingListI
nter
,
64
);
memcpy
(
sl
->
sl
[
2
][
5
],
default_scaling_list_i
nter
,
64
);
memcpy
(
sl
->
aaau8Sl
[
2
][
5
],
sg_au8DefaultScalingListI
nter
,
64
);
memcpy
(
sl
->
sl
[
3
][
0
],
default_scaling_list_i
ntra
,
64
);
memcpy
(
sl
->
aaau8Sl
[
3
][
0
],
sg_au8DefaultScalingListI
ntra
,
64
);
memcpy
(
sl
->
sl
[
3
][
1
],
default_scaling_list_i
ntra
,
64
);
memcpy
(
sl
->
aaau8Sl
[
3
][
1
],
sg_au8DefaultScalingListI
ntra
,
64
);
memcpy
(
sl
->
sl
[
3
][
2
],
default_scaling_list_i
ntra
,
64
);
memcpy
(
sl
->
aaau8Sl
[
3
][
2
],
sg_au8DefaultScalingListI
ntra
,
64
);
memcpy
(
sl
->
sl
[
3
][
3
],
default_scaling_list_i
nter
,
64
);
memcpy
(
sl
->
aaau8Sl
[
3
][
3
],
sg_au8DefaultScalingListI
nter
,
64
);
memcpy
(
sl
->
sl
[
3
][
4
],
default_scaling_list_i
nter
,
64
);
memcpy
(
sl
->
aaau8Sl
[
3
][
4
],
sg_au8DefaultScalingListI
nter
,
64
);
memcpy
(
sl
->
sl
[
3
][
5
],
default_scaling_list_i
nter
,
64
);
memcpy
(
sl
->
aaau8Sl
[
3
][
5
],
sg_au8DefaultScalingListI
nter
,
64
);
}
}
static
int
scalingListData
(
T_GetBitContext
*
pvBuf
,
T_ScalingList
*
sl
,
T_HEVCSPS
*
s
ps
)
static
int
scalingListData
(
T_GetBitContext
*
pvBuf
,
T_ScalingList
*
sl
,
T_HEVCSPS
*
ptS
ps
)
{
{
uint8_t
scaling_list_pred_mode_flag
;
uint8_t
scaling_list_pred_mode_flag
;
int32_t
scaling_list_dc_coef
[
2
][
6
];
int32_t
scaling_list_dc_coef
[
2
][
6
];
...
@@ -1262,11 +1262,11 @@ static int scalingListData(T_GetBitContext *pvBuf, T_ScalingList *sl, T_HEVCSPS
...
@@ -1262,11 +1262,11 @@ static int scalingListData(T_GetBitContext *pvBuf, T_ScalingList *sl, T_HEVCSPS
return
-
1
;
return
-
1
;
}
}
memcpy
(
sl
->
s
l
[
size_id
][
matrix_id
],
memcpy
(
sl
->
aaau8S
l
[
size_id
][
matrix_id
],
sl
->
s
l
[
size_id
][
matrix_id
-
delta
],
sl
->
aaau8S
l
[
size_id
][
matrix_id
-
delta
],
size_id
>
0
?
64
:
16
);
size_id
>
0
?
64
:
16
);
if
(
size_id
>
1
)
if
(
size_id
>
1
)
sl
->
sl_dc
[
size_id
-
2
][
matrix_id
]
=
sl
->
sl_d
c
[
size_id
-
2
][
matrix_id
-
delta
];
sl
->
aau8SlDc
[
size_id
-
2
][
matrix_id
]
=
sl
->
aau8SlD
c
[
size_id
-
2
][
matrix_id
-
delta
];
}
}
}
else
{
}
else
{
int
next_coef
,
coef_num
;
int
next_coef
,
coef_num
;
...
@@ -1277,34 +1277,34 @@ static int scalingListData(T_GetBitContext *pvBuf, T_ScalingList *sl, T_HEVCSPS
...
@@ -1277,34 +1277,34 @@ static int scalingListData(T_GetBitContext *pvBuf, T_ScalingList *sl, T_HEVCSPS
if
(
size_id
>
1
)
{
if
(
size_id
>
1
)
{
scaling_list_dc_coef
[
size_id
-
2
][
matrix_id
]
=
parseSe
(
pvBuf
)
+
8
;
scaling_list_dc_coef
[
size_id
-
2
][
matrix_id
]
=
parseSe
(
pvBuf
)
+
8
;
next_coef
=
scaling_list_dc_coef
[
size_id
-
2
][
matrix_id
];
next_coef
=
scaling_list_dc_coef
[
size_id
-
2
][
matrix_id
];
sl
->
sl_d
c
[
size_id
-
2
][
matrix_id
]
=
next_coef
;
sl
->
aau8SlD
c
[
size_id
-
2
][
matrix_id
]
=
next_coef
;
}
}
for
(
i
=
0
;
i
<
coef_num
;
i
++
)
{
for
(
i
=
0
;
i
<
coef_num
;
i
++
)
{
if
(
size_id
==
0
)
if
(
size_id
==
0
)
pos
=
4
*
ff_hevc_diag_scan4x4_y
[
i
]
+
pos
=
4
*
g_au8HevcDiagScan4x4Y
[
i
]
+
ff_hevc_diag_scan4x4_x
[
i
];
g_au8HevcDiagScan4x4X
[
i
];
else
else
pos
=
8
*
ff_hevc_diag_scan8x8_y
[
i
]
+
pos
=
8
*
g_au8HevcDiagScan8x8Y
[
i
]
+
ff_hevc_diag_scan8x8_x
[
i
];
g_au8HevcDiagScan8x8X
[
i
];
scaling_list_delta_coef
=
parseSe
(
pvBuf
);
scaling_list_delta_coef
=
parseSe
(
pvBuf
);
next_coef
=
(
next_coef
+
256U
+
scaling_list_delta_coef
)
%
256
;
next_coef
=
(
next_coef
+
256U
+
scaling_list_delta_coef
)
%
256
;
sl
->
s
l
[
size_id
][
matrix_id
][
pos
]
=
next_coef
;
sl
->
aaau8S
l
[
size_id
][
matrix_id
][
pos
]
=
next_coef
;
}
}
}
}
}
}
if
(
sps
->
chroma_format_i
dc
==
3
)
{
if
(
ptSps
->
iChromaFormatI
dc
==
3
)
{
for
(
i
=
0
;
i
<
64
;
i
++
)
{
for
(
i
=
0
;
i
<
64
;
i
++
)
{
sl
->
sl
[
3
][
1
][
i
]
=
sl
->
s
l
[
2
][
1
][
i
];
sl
->
aaau8Sl
[
3
][
1
][
i
]
=
sl
->
aaau8S
l
[
2
][
1
][
i
];
sl
->
sl
[
3
][
2
][
i
]
=
sl
->
s
l
[
2
][
2
][
i
];
sl
->
aaau8Sl
[
3
][
2
][
i
]
=
sl
->
aaau8S
l
[
2
][
2
][
i
];
sl
->
sl
[
3
][
4
][
i
]
=
sl
->
s
l
[
2
][
4
][
i
];
sl
->
aaau8Sl
[
3
][
4
][
i
]
=
sl
->
aaau8S
l
[
2
][
4
][
i
];
sl
->
sl
[
3
][
5
][
i
]
=
sl
->
s
l
[
2
][
5
][
i
];
sl
->
aaau8Sl
[
3
][
5
][
i
]
=
sl
->
aaau8S
l
[
2
][
5
][
i
];
}
}
sl
->
sl_dc
[
1
][
1
]
=
sl
->
sl_d
c
[
0
][
1
];
sl
->
aau8SlDc
[
1
][
1
]
=
sl
->
aau8SlD
c
[
0
][
1
];
sl
->
sl_dc
[
1
][
2
]
=
sl
->
sl_d
c
[
0
][
2
];
sl
->
aau8SlDc
[
1
][
2
]
=
sl
->
aau8SlD
c
[
0
][
2
];
sl
->
sl_dc
[
1
][
4
]
=
sl
->
sl_d
c
[
0
][
4
];
sl
->
aau8SlDc
[
1
][
4
]
=
sl
->
aau8SlD
c
[
0
][
4
];
sl
->
sl_dc
[
1
][
5
]
=
sl
->
sl_d
c
[
0
][
5
];
sl
->
aau8SlDc
[
1
][
5
]
=
sl
->
aau8SlD
c
[
0
][
5
];
}
}
...
@@ -1312,60 +1312,60 @@ static int scalingListData(T_GetBitContext *pvBuf, T_ScalingList *sl, T_HEVCSPS
...
@@ -1312,60 +1312,60 @@ static int scalingListData(T_GetBitContext *pvBuf, T_ScalingList *sl, T_HEVCSPS
}
}
int
hevcDecodeShortTermRps
(
T_GetBitContext
*
pvBuf
,
int
hevcDecodeShortTermRps
(
T_GetBitContext
*
pvBuf
,
T_ShortTermRPS
*
rps
,
const
T_HEVCSPS
*
s
ps
,
int
is_slice_header
)
T_ShortTermRPS
*
rps
,
const
T_HEVCSPS
*
ptS
ps
,
int
is_slice_header
)
{
{
uint8_t
rps_predict
=
0
;
uint8_t
rps_predict
=
0
;
int
delta_p
oc
;
int
au32DeltaP
oc
;
int
k0
=
0
;
int
k0
=
0
;
int
k1
=
0
;
int
k1
=
0
;
int
k
=
0
;
int
k
=
0
;
int
i
;
int
i
;
if
(
rps
!=
sps
->
st_rps
&&
sps
->
nb_st_r
ps
)
if
(
rps
!=
ptSps
->
atStRps
&&
ptSps
->
uiNbStR
ps
)
rps_predict
=
getOneBit
(
pvBuf
);
rps_predict
=
getOneBit
(
pvBuf
);
if
(
rps_predict
)
{
if
(
rps_predict
)
{
const
T_ShortTermRPS
*
rps_r
idx
;
const
T_ShortTermRPS
*
ptRpsR
idx
;
int
delta_r
ps
;
int
iDeltaR
ps
;
unsigned
abs_delta_r
ps
;
unsigned
int
uiAbsDeltaR
ps
;
uint8_t
u
se_delta_f
lag
=
0
;
uint8_t
u
8UseDeltaF
lag
=
0
;
uint8_t
delta_rps_s
ign
;
uint8_t
u8DeltaRpsS
ign
;
if
(
is_slice_header
)
{
if
(
is_slice_header
)
{
unsigned
int
delta_i
dx
=
parseUe
(
pvBuf
)
+
1
;
unsigned
int
uiDeltaI
dx
=
parseUe
(
pvBuf
)
+
1
;
if
(
delta_idx
>
sps
->
nb_st_r
ps
)
{
if
(
u8DeltaRpsSign
>
ptSps
->
uiNbStR
ps
)
{
RPT
(
RPT_ERR
,
RPT
(
RPT_ERR
,
"Invalid value of delta_idx in slice header RPS: %d > %d.
\n
"
,
"Invalid value of delta_idx in slice header RPS: %d > %d.
\n
"
,
delta_idx
,
sps
->
nb_st_r
ps
);
u8DeltaRpsSign
,
ptSps
->
uiNbStR
ps
);
return
-
1
;
return
-
1
;
}
}
rps_ridx
=
&
sps
->
st_rps
[
sps
->
nb_st_rps
-
delta_idx
];
ptRpsRidx
=
&
ptSps
->
atStRps
[
ptSps
->
uiNbStRps
-
u8DeltaRpsSign
];
rps
->
rps_idx_num_delta_pocs
=
rps_ridx
->
num_delta_p
ocs
;
rps
->
iRpsIdxNumDeltaPocs
=
ptRpsRidx
->
iNumDeltaP
ocs
;
}
else
}
else
rps_ridx
=
&
sps
->
st_rps
[
rps
-
sps
->
st_r
ps
-
1
];
ptRpsRidx
=
&
ptSps
->
atStRps
[
rps
-
ptSps
->
atStR
ps
-
1
];
delta_rps_s
ign
=
getOneBit
(
pvBuf
);
u8DeltaRpsS
ign
=
getOneBit
(
pvBuf
);
abs_delta_r
ps
=
parseUe
(
pvBuf
)
+
1
;
uiAbsDeltaR
ps
=
parseUe
(
pvBuf
)
+
1
;
if
(
abs_delta_rps
<
1
||
abs_delta_r
ps
>
32768
)
{
if
(
uiAbsDeltaRps
<
1
||
uiAbsDeltaR
ps
>
32768
)
{
RPT
(
RPT_ERR
,
RPT
(
RPT_ERR
,
"Invalid value of
abs_delta_r
ps: %d
\n
"
,
"Invalid value of
uiAbsDeltaR
ps: %d
\n
"
,
abs_delta_r
ps
);
uiAbsDeltaR
ps
);
return
-
1
;
return
-
1
;
}
}
delta_rps
=
(
1
-
(
delta_rps_sign
<<
1
))
*
abs_delta_r
ps
;
iDeltaRps
=
(
1
-
(
u8DeltaRpsSign
<<
1
))
*
uiAbsDeltaR
ps
;
for
(
i
=
0
;
i
<=
rps_ridx
->
num_delta_p
ocs
;
i
++
)
{
for
(
i
=
0
;
i
<=
ptRpsRidx
->
iNumDeltaP
ocs
;
i
++
)
{
int
used
=
rps
->
u
sed
[
k
]
=
getOneBit
(
pvBuf
);
int
used
=
rps
->
au8U
sed
[
k
]
=
getOneBit
(
pvBuf
);
if
(
!
used
)
if
(
!
used
)
u
se_delta_f
lag
=
getOneBit
(
pvBuf
);
u
8UseDeltaF
lag
=
getOneBit
(
pvBuf
);
if
(
used
||
u
se_delta_f
lag
)
{
if
(
used
||
u
8UseDeltaF
lag
)
{
if
(
i
<
rps_ridx
->
num_delta_p
ocs
)
if
(
i
<
ptRpsRidx
->
iNumDeltaP
ocs
)
delta_poc
=
delta_rps
+
rps_ridx
->
delta_p
oc
[
i
];
au32DeltaPoc
=
iDeltaRps
+
ptRpsRidx
->
au32DeltaP
oc
[
i
];
else
else
delta_poc
=
delta_r
ps
;
au32DeltaPoc
=
iDeltaR
ps
;
rps
->
delta_poc
[
k
]
=
delta_p
oc
;
rps
->
au32DeltaPoc
[
k
]
=
au32DeltaP
oc
;
if
(
delta_p
oc
<
0
)
if
(
au32DeltaP
oc
<
0
)
k0
++
;
k0
++
;
else
else
k1
++
;
k1
++
;
...
@@ -1373,83 +1373,83 @@ int hevcDecodeShortTermRps(T_GetBitContext *pvBuf,
...
@@ -1373,83 +1373,83 @@ int hevcDecodeShortTermRps(T_GetBitContext *pvBuf,
}
}
}
}
if
(
k
>=
FF_ARRAY_ELEMS
(
rps
->
u
sed
))
{
if
(
k
>=
FF_ARRAY_ELEMS
(
rps
->
au8U
sed
))
{
RPT
(
RPT_ERR
,
RPT
(
RPT_ERR
,
"Invalid
num_delta_p
ocs: %d
\n
"
,
k
);
"Invalid
iNumDeltaP
ocs: %d
\n
"
,
k
);
return
-
1
;
return
-
1
;
}
}
rps
->
num_delta_p
ocs
=
k
;
rps
->
iNumDeltaP
ocs
=
k
;
rps
->
num_negative_p
ics
=
k0
;
rps
->
uiNumNegativeP
ics
=
k0
;
// sort in increasing order (smallest first)
// sort in increasing order (smallest first)
if
(
rps
->
num_delta_p
ocs
!=
0
)
{
if
(
rps
->
iNumDeltaP
ocs
!=
0
)
{
int
used
,
tmp
;
int
used
,
tmp
;
for
(
i
=
1
;
i
<
rps
->
num_delta_p
ocs
;
i
++
)
{
for
(
i
=
1
;
i
<
rps
->
iNumDeltaP
ocs
;
i
++
)
{
delta_poc
=
rps
->
delta_p
oc
[
i
];
au32DeltaPoc
=
rps
->
au32DeltaP
oc
[
i
];
used
=
rps
->
u
sed
[
i
];
used
=
rps
->
au8U
sed
[
i
];
for
(
k
=
i
-
1
;
k
>=
0
;
k
--
)
{
for
(
k
=
i
-
1
;
k
>=
0
;
k
--
)
{
tmp
=
rps
->
delta_p
oc
[
k
];
tmp
=
rps
->
au32DeltaP
oc
[
k
];
if
(
delta_p
oc
<
tmp
)
{
if
(
au32DeltaP
oc
<
tmp
)
{
rps
->
delta_p
oc
[
k
+
1
]
=
tmp
;
rps
->
au32DeltaP
oc
[
k
+
1
]
=
tmp
;
rps
->
used
[
k
+
1
]
=
rps
->
u
sed
[
k
];
rps
->
au8Used
[
k
+
1
]
=
rps
->
au8U
sed
[
k
];
rps
->
delta_poc
[
k
]
=
delta_p
oc
;
rps
->
au32DeltaPoc
[
k
]
=
au32DeltaP
oc
;
rps
->
u
sed
[
k
]
=
used
;
rps
->
au8U
sed
[
k
]
=
used
;
}
}
}
}
}
}
}
}
if
((
rps
->
num_negative_p
ics
>>
1
)
!=
0
)
{
if
((
rps
->
uiNumNegativeP
ics
>>
1
)
!=
0
)
{
int
used
;
int
used
;
k
=
rps
->
num_negative_p
ics
-
1
;
k
=
rps
->
uiNumNegativeP
ics
-
1
;
// flip the negative values to largest first
// flip the negative values to largest first
for
(
i
=
0
;
i
<
rps
->
num_negative_p
ics
>>
1
;
i
++
)
{
for
(
i
=
0
;
i
<
rps
->
uiNumNegativeP
ics
>>
1
;
i
++
)
{
delta_poc
=
rps
->
delta_p
oc
[
i
];
au32DeltaPoc
=
rps
->
au32DeltaP
oc
[
i
];
used
=
rps
->
u
sed
[
i
];
used
=
rps
->
au8U
sed
[
i
];
rps
->
delta_poc
[
i
]
=
rps
->
delta_p
oc
[
k
];
rps
->
au32DeltaPoc
[
i
]
=
rps
->
au32DeltaP
oc
[
k
];
rps
->
used
[
i
]
=
rps
->
u
sed
[
k
];
rps
->
au8Used
[
i
]
=
rps
->
au8U
sed
[
k
];
rps
->
delta_poc
[
k
]
=
delta_p
oc
;
rps
->
au32DeltaPoc
[
k
]
=
au32DeltaP
oc
;
rps
->
u
sed
[
k
]
=
used
;
rps
->
au8U
sed
[
k
]
=
used
;
k
--
;
k
--
;
}
}
}
}
}
else
{
}
else
{
unsigned
int
prev
,
nb_positive_p
ics
;
unsigned
int
uiPrev
,
uiNbPositiveP
ics
;
rps
->
num_negative_p
ics
=
parseUe
(
pvBuf
);
rps
->
uiNumNegativeP
ics
=
parseUe
(
pvBuf
);
nb_positive_p
ics
=
parseUe
(
pvBuf
);
uiNbPositiveP
ics
=
parseUe
(
pvBuf
);
if
(
rps
->
num_negative_p
ics
>=
HEVC_MAX_REFS
||
if
(
rps
->
uiNumNegativeP
ics
>=
HEVC_MAX_REFS
||
nb_positive_p
ics
>=
HEVC_MAX_REFS
)
{
uiNbPositiveP
ics
>=
HEVC_MAX_REFS
)
{
RPT
(
RPT_ERR
,
"Too many refs in a short term RPS.
\n
"
);
RPT
(
RPT_ERR
,
"Too many refs in a short term RPS.
\n
"
);
return
-
1
;
return
-
1
;
}
}
rps
->
num_delta_pocs
=
rps
->
num_negative_pics
+
nb_positive_p
ics
;
rps
->
iNumDeltaPocs
=
rps
->
uiNumNegativePics
+
uiNbPositiveP
ics
;
if
(
rps
->
num_delta_p
ocs
)
{
if
(
rps
->
iNumDeltaP
ocs
)
{
p
rev
=
0
;
uiP
rev
=
0
;
for
(
i
=
0
;
i
<
rps
->
num_negative_p
ics
;
i
++
)
{
for
(
i
=
0
;
i
<
rps
->
uiNumNegativeP
ics
;
i
++
)
{
delta_p
oc
=
parseUe
(
pvBuf
)
+
1
;
au32DeltaP
oc
=
parseUe
(
pvBuf
)
+
1
;
if
(
delta_poc
<
1
||
delta_p
oc
>
32768
)
{
if
(
au32DeltaPoc
<
1
||
au32DeltaP
oc
>
32768
)
{
RPT
(
RPT_ERR
,
RPT
(
RPT_ERR
,
"Invalid value of
delta_p
oc: %d
\n
"
,
"Invalid value of
au32DeltaP
oc: %d
\n
"
,
delta_p
oc
);
au32DeltaP
oc
);
return
-
1
;
return
-
1
;
}
}
prev
-=
delta_p
oc
;
uiPrev
-=
au32DeltaP
oc
;
rps
->
delta_poc
[
i
]
=
p
rev
;
rps
->
au32DeltaPoc
[
i
]
=
uiP
rev
;
rps
->
u
sed
[
i
]
=
getOneBit
(
pvBuf
);
rps
->
au8U
sed
[
i
]
=
getOneBit
(
pvBuf
);
}
}
p
rev
=
0
;
uiP
rev
=
0
;
for
(
i
=
0
;
i
<
nb_positive_p
ics
;
i
++
)
{
for
(
i
=
0
;
i
<
uiNbPositiveP
ics
;
i
++
)
{
delta_p
oc
=
parseUe
(
pvBuf
)
+
1
;
au32DeltaP
oc
=
parseUe
(
pvBuf
)
+
1
;
if
(
delta_poc
<
1
||
delta_p
oc
>
32768
)
{
if
(
au32DeltaPoc
<
1
||
au32DeltaP
oc
>
32768
)
{
RPT
(
RPT_ERR
,
RPT
(
RPT_ERR
,
"Invalid value of
delta_p
oc: %d
\n
"
,
"Invalid value of
au32DeltaP
oc: %d
\n
"
,
delta_p
oc
);
au32DeltaP
oc
);
return
-
1
;
return
-
1
;
}
}
prev
+=
delta_p
oc
;
uiPrev
+=
au32DeltaP
oc
;
rps
->
delta_poc
[
rps
->
num_negative_pics
+
i
]
=
p
rev
;
rps
->
au32DeltaPoc
[
rps
->
uiNumNegativePics
+
i
]
=
uiP
rev
;
rps
->
used
[
rps
->
num_negative_p
ics
+
i
]
=
getOneBit
(
pvBuf
);
rps
->
au8Used
[
rps
->
uiNumNegativeP
ics
+
i
]
=
getOneBit
(
pvBuf
);
}
}
}
}
}
}
...
@@ -1457,7 +1457,7 @@ int hevcDecodeShortTermRps(T_GetBitContext *pvBuf,
...
@@ -1457,7 +1457,7 @@ int hevcDecodeShortTermRps(T_GetBitContext *pvBuf,
}
}
static
void
decodeSublayerHrd
(
T_GetBitContext
*
pvBuf
,
unsigned
int
nb_cpb
,
static
void
decodeSublayerHrd
(
T_GetBitContext
*
pvBuf
,
unsigned
int
nb_cpb
,
int
subpic_params_p
resent
)
int
iSubpicParamsP
resent
)
{
{
int
i
;
int
i
;
...
@@ -1465,7 +1465,7 @@ static void decodeSublayerHrd(T_GetBitContext *pvBuf, unsigned int nb_cpb,
...
@@ -1465,7 +1465,7 @@ static void decodeSublayerHrd(T_GetBitContext *pvBuf, unsigned int nb_cpb,
parseUe
(
pvBuf
);
// bit_rate_value_minus1
parseUe
(
pvBuf
);
// bit_rate_value_minus1
parseUe
(
pvBuf
);
// cpb_size_value_minus1
parseUe
(
pvBuf
);
// cpb_size_value_minus1
if
(
subpic_params_p
resent
)
{
if
(
iSubpicParamsP
resent
)
{
parseUe
(
pvBuf
);
// cpb_size_du_value_minus1
parseUe
(
pvBuf
);
// cpb_size_du_value_minus1
parseUe
(
pvBuf
);
// bit_rate_du_value_minus1
parseUe
(
pvBuf
);
// bit_rate_du_value_minus1
}
}
...
@@ -1476,18 +1476,18 @@ static void decodeSublayerHrd(T_GetBitContext *pvBuf, unsigned int nb_cpb,
...
@@ -1476,18 +1476,18 @@ static void decodeSublayerHrd(T_GetBitContext *pvBuf, unsigned int nb_cpb,
static
int
decodeHrd
(
T_GetBitContext
*
pvBuf
,
int
common_inf_present
,
static
int
decodeHrd
(
T_GetBitContext
*
pvBuf
,
int
common_inf_present
,
int
max_sublayers
)
int
max_sublayers
)
{
{
int
nal_params_present
=
0
,
vcl_params_p
resent
=
0
;
int
iNalParamsPresent
=
0
,
iVclParamsP
resent
=
0
;
int
subpic_params_p
resent
=
0
;
int
iSubpicParamsP
resent
=
0
;
int
i
;
int
i
;
if
(
common_inf_present
)
{
if
(
common_inf_present
)
{
nal_params_p
resent
=
getOneBit
(
pvBuf
);
iNalParamsP
resent
=
getOneBit
(
pvBuf
);
vcl_params_p
resent
=
getOneBit
(
pvBuf
);
iVclParamsP
resent
=
getOneBit
(
pvBuf
);
if
(
nal_params_present
||
vcl_params_p
resent
)
{
if
(
iNalParamsPresent
||
iVclParamsP
resent
)
{
subpic_params_p
resent
=
getOneBit
(
pvBuf
);
iSubpicParamsP
resent
=
getOneBit
(
pvBuf
);
if
(
subpic_params_p
resent
)
{
if
(
iSubpicParamsP
resent
)
{
getBits
(
pvBuf
,
8
);
// tick_divisor_minus2
getBits
(
pvBuf
,
8
);
// tick_divisor_minus2
getBits
(
pvBuf
,
5
);
// du_cpb_removal_delay_increment_length_minus1
getBits
(
pvBuf
,
5
);
// du_cpb_removal_delay_increment_length_minus1
getBits
(
pvBuf
,
1
);
// sub_pic_cpb_params_in_pic_timing_sei_flag
getBits
(
pvBuf
,
1
);
// sub_pic_cpb_params_in_pic_timing_sei_flag
...
@@ -1497,7 +1497,7 @@ static int decodeHrd(T_GetBitContext *pvBuf, int common_inf_present,
...
@@ -1497,7 +1497,7 @@ static int decodeHrd(T_GetBitContext *pvBuf, int common_inf_present,
getBits
(
pvBuf
,
4
);
// bit_rate_scale
getBits
(
pvBuf
,
4
);
// bit_rate_scale
getBits
(
pvBuf
,
4
);
// cpb_size_scale
getBits
(
pvBuf
,
4
);
// cpb_size_scale
if
(
subpic_params_p
resent
)
if
(
iSubpicParamsP
resent
)
getBits
(
pvBuf
,
4
);
// cpb_size_du_scale
getBits
(
pvBuf
,
4
);
// cpb_size_du_scale
getBits
(
pvBuf
,
5
);
// initial_cpb_removal_delay_length_minus1
getBits
(
pvBuf
,
5
);
// initial_cpb_removal_delay_length_minus1
...
@@ -1509,12 +1509,12 @@ static int decodeHrd(T_GetBitContext *pvBuf, int common_inf_present,
...
@@ -1509,12 +1509,12 @@ static int decodeHrd(T_GetBitContext *pvBuf, int common_inf_present,
for
(
i
=
0
;
i
<
max_sublayers
;
i
++
)
{
for
(
i
=
0
;
i
<
max_sublayers
;
i
++
)
{
int
low_delay
=
0
;
int
low_delay
=
0
;
unsigned
int
nb_cpb
=
1
;
unsigned
int
nb_cpb
=
1
;
int
fixed_r
ate
=
getOneBit
(
pvBuf
);
int
iFixedR
ate
=
getOneBit
(
pvBuf
);
if
(
!
fixed_r
ate
)
if
(
!
iFixedR
ate
)
fixed_r
ate
=
getOneBit
(
pvBuf
);
iFixedR
ate
=
getOneBit
(
pvBuf
);
if
(
fixed_r
ate
)
if
(
iFixedR
ate
)
parseUe
(
pvBuf
);
// elemental_duration_in_tc_minus1
parseUe
(
pvBuf
);
// elemental_duration_in_tc_minus1
else
else
low_delay
=
getOneBit
(
pvBuf
);
low_delay
=
getOneBit
(
pvBuf
);
...
@@ -1527,20 +1527,20 @@ static int decodeHrd(T_GetBitContext *pvBuf, int common_inf_present,
...
@@ -1527,20 +1527,20 @@ static int decodeHrd(T_GetBitContext *pvBuf, int common_inf_present,
}
}
}
}
if
(
nal_params_p
resent
)
if
(
iNalParamsP
resent
)
decodeSublayerHrd
(
pvBuf
,
nb_cpb
,
subpic_params_p
resent
);
decodeSublayerHrd
(
pvBuf
,
nb_cpb
,
iSubpicParamsP
resent
);
if
(
vcl_params_p
resent
)
if
(
iVclParamsP
resent
)
decodeSublayerHrd
(
pvBuf
,
nb_cpb
,
subpic_params_p
resent
);
decodeSublayerHrd
(
pvBuf
,
nb_cpb
,
iSubpicParamsP
resent
);
}
}
return
0
;
return
0
;
}
}
static
void
decodeVui
(
T_GetBitContext
*
pvBuf
,
T_HEVCSPS
*
s
ps
)
static
void
decodeVui
(
T_GetBitContext
*
pvBuf
,
T_HEVCSPS
*
ptS
ps
)
{
{
T_VUI
backup_vui
,
*
vui
=
&
sps
->
v
ui
;
T_VUI
tBackupVui
,
*
tVui
=
&
ptSps
->
tV
ui
;
T_GetBitContext
b
ackup
;
T_GetBitContext
tB
ackup
;
int
sar_present
,
alt
=
0
;
int
sar_present
,
alt
=
0
;
RPT
(
RPT_DBG
,
"Decoding VUI
\n
"
);
RPT
(
RPT_DBG
,
"Decoding VUI
\n
"
);
...
@@ -1548,166 +1548,145 @@ static void decodeVui(T_GetBitContext *pvBuf, T_HEVCSPS *sps)
...
@@ -1548,166 +1548,145 @@ static void decodeVui(T_GetBitContext *pvBuf, T_HEVCSPS *sps)
sar_present
=
getOneBit
(
pvBuf
);
sar_present
=
getOneBit
(
pvBuf
);
if
(
sar_present
)
{
if
(
sar_present
)
{
uint8_t
sar_idx
=
getBits
(
pvBuf
,
8
);
uint8_t
sar_idx
=
getBits
(
pvBuf
,
8
);
if
(
sar_idx
<
FF_ARRAY_ELEMS
(
vui_s
ar
))
if
(
sar_idx
<
FF_ARRAY_ELEMS
(
sg_atVuiS
ar
))
vui
->
sar
=
vui_s
ar
[
sar_idx
];
tVui
->
tSar
=
sg_atVuiS
ar
[
sar_idx
];
else
if
(
sar_idx
==
255
)
{
else
if
(
sar_idx
==
255
)
{
vui
->
s
ar
.
num
=
getBits
(
pvBuf
,
16
);
tVui
->
tS
ar
.
num
=
getBits
(
pvBuf
,
16
);
vui
->
s
ar
.
den
=
getBits
(
pvBuf
,
16
);
tVui
->
tS
ar
.
den
=
getBits
(
pvBuf
,
16
);
}
else
}
else
RPT
(
RPT_WRN
,
RPT
(
RPT_WRN
,
"Unknown SAR index: %u.
\n
"
,
sar_idx
);
"Unknown SAR index: %u.
\n
"
,
sar_idx
);
}
}
vui
->
overscan_info_present_flag
=
getOneBit
(
pvBuf
);
tVui
->
iOverscanInfoPresentFlag
=
getOneBit
(
pvBuf
);
if
(
vui
->
overscan_info_present_flag
)
if
(
tVui
->
iOverscanInfoPresentFlag
)
vui
->
overscan_appropriate_flag
=
getOneBit
(
pvBuf
);
tVui
->
iOverscanAppropriateFlag
=
getOneBit
(
pvBuf
);
vui
->
video_signal_type_present_flag
=
getOneBit
(
pvBuf
);
tVui
->
iVideoSignalTypePresentFlag
=
getOneBit
(
pvBuf
);
if
(
vui
->
video_signal_type_present_flag
)
{
if
(
tVui
->
iVideoSignalTypePresentFlag
)
{
vui
->
video_format
=
getBits
(
pvBuf
,
3
);
tVui
->
iVideoFormat
=
getBits
(
pvBuf
,
3
);
vui
->
video_full_range_flag
=
getOneBit
(
pvBuf
);
tVui
->
iVideoFullRangeFlag
=
getOneBit
(
pvBuf
);
vui
->
colour_description_present_flag
=
getOneBit
(
pvBuf
);
tVui
->
iColourDescriptionPresentFlag
=
getOneBit
(
pvBuf
);
// if (vui->video_full_range_flag && sps->pix_fmt == AV_PIX_FMT_YUV420P)
// if (tVui->iVideoFullRangeFlag && ptSps->pix_fmt == AV_PIX_FMT_YUV420P)
// sps->pix_fmt = AV_PIX_FMT_YUVJ420P;
// ptSps->pix_fmt = AV_PIX_FMT_YUVJ420P;
if
(
vui
->
colour_description_present_flag
)
{
if
(
tVui
->
iColourDescriptionPresentFlag
)
{
vui
->
colour_primaries
=
getBits
(
pvBuf
,
8
);
tVui
->
u8ColourPrimaries
=
getBits
(
pvBuf
,
8
);
vui
->
transfer_characteristic
=
getBits
(
pvBuf
,
8
);
tVui
->
u8TransferCharacteristic
=
getBits
(
pvBuf
,
8
);
vui
->
matrix_coeffs
=
getBits
(
pvBuf
,
8
);
tVui
->
u8MatrixCoeffs
=
getBits
(
pvBuf
,
8
);
#if 0
// Set invalid values to "unspecified"
if (!av_color_primaries_name(vui->colour_primaries))
vui->colour_primaries = AVCOL_PRI_UNSPECIFIED;
if (!av_color_transfer_name(vui->transfer_characteristic))
vui->transfer_characteristic = AVCOL_TRC_UNSPECIFIED;
if (!av_color_space_name(vui->matrix_coeffs))
vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED;
if (vui->matrix_coeffs == AVCOL_SPC_RGB) {
switch (sps->pix_fmt) {
case AV_PIX_FMT_YUV444P:
sps->pix_fmt = AV_PIX_FMT_GBRP;
break;
case AV_PIX_FMT_YUV444P10:
sps->pix_fmt = AV_PIX_FMT_GBRP10;
break;
case AV_PIX_FMT_YUV444P12:
sps->pix_fmt = AV_PIX_FMT_GBRP12;
break;
}
}
#endif
}
}
}
}
vui
->
chroma_loc_info_present_f
lag
=
getOneBit
(
pvBuf
);
tVui
->
iChromaLocInfoPresentF
lag
=
getOneBit
(
pvBuf
);
if
(
vui
->
chroma_loc_info_present_f
lag
)
{
if
(
tVui
->
iChromaLocInfoPresentF
lag
)
{
vui
->
chroma_sample_loc_type_top_f
ield
=
parseUe
(
pvBuf
);
tVui
->
iChromaSampleLocTypeTopF
ield
=
parseUe
(
pvBuf
);
vui
->
chroma_sample_loc_type_bottom_f
ield
=
parseUe
(
pvBuf
);
tVui
->
iChromaSampleLocTypeBottomF
ield
=
parseUe
(
pvBuf
);
}
}
vui
->
neutra_chroma_indication_f
lag
=
getOneBit
(
pvBuf
);
tVui
->
iNeutraChromaIndicationF
lag
=
getOneBit
(
pvBuf
);
vui
->
field_seq_flag
=
getOneBit
(
pvBuf
);
tVui
->
iFieldSeqFlag
=
getOneBit
(
pvBuf
);
vui
->
frame_field_info_present_flag
=
getOneBit
(
pvBuf
);
tVui
->
iFrameFieldInfoPresentFlag
=
getOneBit
(
pvBuf
);
// Backup context in case an alternate header is detected
// Backup context in case an alternate header is detected
memcpy
(
&
backup
,
pvBuf
,
sizeof
(
b
ackup
));
memcpy
(
&
tBackup
,
pvBuf
,
sizeof
(
tB
ackup
));
memcpy
(
&
backup_vui
,
vui
,
sizeof
(
backup_v
ui
));
memcpy
(
&
tBackupVui
,
tVui
,
sizeof
(
tBackupV
ui
));
if
(
getBitsLeft
(
pvBuf
)
>=
68
&&
showBitsLong
(
pvBuf
,
21
)
==
0x100000
)
{
if
(
getBitsLeft
(
pvBuf
)
>=
68
&&
showBitsLong
(
pvBuf
,
21
)
==
0x100000
)
{
vui
->
default_display_window_f
lag
=
0
;
tVui
->
iDefaultDisplayWindowF
lag
=
0
;
RPT
(
RPT_WRN
,
"Invalid default display window
\n
"
);
RPT
(
RPT_WRN
,
"Invalid default display window
\n
"
);
}
else
}
else
vui
->
default_display_window_f
lag
=
getOneBit
(
pvBuf
);
tVui
->
iDefaultDisplayWindowF
lag
=
getOneBit
(
pvBuf
);
if
(
vui
->
default_display_window_f
lag
)
{
if
(
tVui
->
iDefaultDisplayWindowF
lag
)
{
int
vert_mult
=
hevc_sub_height_c
[
sps
->
chroma_format_i
dc
];
int
vert_mult
=
sg_au8HevcSubHeightC
[
ptSps
->
iChromaFormatI
dc
];
int
horiz_mult
=
hevc_sub_width_c
[
sps
->
chroma_format_i
dc
];
int
horiz_mult
=
sg_au8HevcSubWidthC
[
ptSps
->
iChromaFormatI
dc
];
vui
->
def_disp_win
.
left_o
ffset
=
parseUe
(
pvBuf
)
*
horiz_mult
;
tVui
->
tDefDispWin
.
uiLeftO
ffset
=
parseUe
(
pvBuf
)
*
horiz_mult
;
vui
->
def_disp_win
.
right_o
ffset
=
parseUe
(
pvBuf
)
*
horiz_mult
;
tVui
->
tDefDispWin
.
uiRightO
ffset
=
parseUe
(
pvBuf
)
*
horiz_mult
;
vui
->
def_disp_win
.
top_o
ffset
=
parseUe
(
pvBuf
)
*
vert_mult
;
tVui
->
tDefDispWin
.
uiTopO
ffset
=
parseUe
(
pvBuf
)
*
vert_mult
;
vui
->
def_disp_win
.
bottom_o
ffset
=
parseUe
(
pvBuf
)
*
vert_mult
;
tVui
->
tDefDispWin
.
uiBottomO
ffset
=
parseUe
(
pvBuf
)
*
vert_mult
;
}
}
timing_info:
timing_info:
vui
->
vui_timing_info_present_f
lag
=
getOneBit
(
pvBuf
);
tVui
->
iVuiTimingInfoPresentF
lag
=
getOneBit
(
pvBuf
);
if
(
vui
->
vui_timing_info_present_f
lag
)
{
if
(
tVui
->
iVuiTimingInfoPresentF
lag
)
{
if
(
getBitsLeft
(
pvBuf
)
<
66
&&
!
alt
)
{
if
(
getBitsLeft
(
pvBuf
)
<
66
&&
!
alt
)
{
// The alternate syntax seem to have timing info located
// The alternate syntax seem to have timing info located
// at where
def_disp_w
in is normally located
// at where
tDefDispW
in is normally located
RPT
(
RPT_WRN
,
RPT
(
RPT_WRN
,
"Strange VUI timing information, retrying...
\n
"
);
"Strange VUI timing information, retrying...
\n
"
);
memcpy
(
vui
,
&
backup_vui
,
sizeof
(
backup_v
ui
));
memcpy
(
tVui
,
&
tBackupVui
,
sizeof
(
tBackupV
ui
));
memcpy
(
pvBuf
,
&
backup
,
sizeof
(
b
ackup
));
memcpy
(
pvBuf
,
&
tBackup
,
sizeof
(
tB
ackup
));
alt
=
1
;
alt
=
1
;
goto
timing_info
;
goto
timing_info
;
}
}
vui
->
vui_num_units_in_t
ick
=
getBits
(
pvBuf
,
32
);
tVui
->
u32VuiNumUnitsInT
ick
=
getBits
(
pvBuf
,
32
);
vui
->
vui_time_s
cale
=
getBits
(
pvBuf
,
32
);
tVui
->
u32VuiTimeS
cale
=
getBits
(
pvBuf
,
32
);
if
(
alt
)
{
if
(
alt
)
{
RPT
(
RPT_INF
,
"Retry got %u/%u fps
\n
"
,
RPT
(
RPT_INF
,
"Retry got %u/%u fps
\n
"
,
vui
->
vui_time_scale
,
vui
->
vui_num_units_in_t
ick
);
tVui
->
u32VuiTimeScale
,
tVui
->
u32VuiNumUnitsInT
ick
);
}
}
vui
->
vui_poc_proportional_to_timing_f
lag
=
getOneBit
(
pvBuf
);
tVui
->
iVuiPocProportionalToTimingF
lag
=
getOneBit
(
pvBuf
);
if
(
vui
->
vui_poc_proportional_to_timing_f
lag
)
if
(
tVui
->
iVuiPocProportionalToTimingF
lag
)
vui
->
vui_num_ticks_poc_diff_one_m
inus1
=
parseUe
(
pvBuf
);
tVui
->
iVuiNumTicksPocDiffOneM
inus1
=
parseUe
(
pvBuf
);
vui
->
vui_hrd_parameters_present_f
lag
=
getOneBit
(
pvBuf
);
tVui
->
iVuiHrdParametersPresentF
lag
=
getOneBit
(
pvBuf
);
if
(
vui
->
vui_hrd_parameters_present_f
lag
)
if
(
tVui
->
iVuiHrdParametersPresentF
lag
)
decodeHrd
(
pvBuf
,
1
,
sps
->
max_sub_l
ayers
);
decodeHrd
(
pvBuf
,
1
,
ptSps
->
iMaxSubL
ayers
);
}
}
vui
->
bitstream_restriction_f
lag
=
getOneBit
(
pvBuf
);
tVui
->
iBitstreamRestrictionF
lag
=
getOneBit
(
pvBuf
);
if
(
vui
->
bitstream_restriction_f
lag
)
{
if
(
tVui
->
iBitstreamRestrictionF
lag
)
{
if
(
getBitsLeft
(
pvBuf
)
<
8
&&
!
alt
)
{
if
(
getBitsLeft
(
pvBuf
)
<
8
&&
!
alt
)
{
RPT
(
RPT_WRN
,
RPT
(
RPT_WRN
,
"Strange VUI bitstream restriction information, retrying"
"Strange VUI bitstream restriction information, retrying"
" from timing information...
\n
"
);
" from timing information...
\n
"
);
memcpy
(
vui
,
&
backup_vui
,
sizeof
(
backup_v
ui
));
memcpy
(
tVui
,
&
tBackupVui
,
sizeof
(
tBackupV
ui
));
memcpy
(
pvBuf
,
&
backup
,
sizeof
(
b
ackup
));
memcpy
(
pvBuf
,
&
tBackup
,
sizeof
(
tB
ackup
));
alt
=
1
;
alt
=
1
;
goto
timing_info
;
goto
timing_info
;
}
}
vui
->
tiles_fixed_structure_f
lag
=
getOneBit
(
pvBuf
);
tVui
->
iTilesFixedStructureF
lag
=
getOneBit
(
pvBuf
);
vui
->
motion_vectors_over_pic_boundaries_flag
=
getOneBit
(
pvBuf
);
tVui
->
iMotionVectorsOverPicBoundariesFlag
=
getOneBit
(
pvBuf
);
vui
->
restricted_ref_pic_lists_flag
=
getOneBit
(
pvBuf
);
tVui
->
iRestrictedRefPicListsFlag
=
getOneBit
(
pvBuf
);
vui
->
min_spatial_segmentation_i
dc
=
parseUe
(
pvBuf
);
tVui
->
iMinSpatialSegmentationI
dc
=
parseUe
(
pvBuf
);
vui
->
max_bytes_per_pic_d
enom
=
parseUe
(
pvBuf
);
tVui
->
iMaxBytesPerPicD
enom
=
parseUe
(
pvBuf
);
vui
->
max_bits_per_min_cu_d
enom
=
parseUe
(
pvBuf
);
tVui
->
iMaxBitsPerMinCuD
enom
=
parseUe
(
pvBuf
);
vui
->
log2_max_mv_length_h
orizontal
=
parseUe
(
pvBuf
);
tVui
->
iLog2MaxMvLengthH
orizontal
=
parseUe
(
pvBuf
);
vui
->
log2_max_mv_length_v
ertical
=
parseUe
(
pvBuf
);
tVui
->
iLog2MaxMvLengthV
ertical
=
parseUe
(
pvBuf
);
}
}
if
(
getBitsLeft
(
pvBuf
)
<
1
&&
!
alt
)
{
if
(
getBitsLeft
(
pvBuf
)
<
1
&&
!
alt
)
{
// XXX: Alternate syntax when
sps_range_extension_f
lag != 0?
// XXX: Alternate syntax when
iSpsRangeExtensionF
lag != 0?
RPT
(
RPT_WRN
,
RPT
(
RPT_WRN
,
"Overread in VUI, retrying from timing information...
\n
"
);
"Overread in VUI, retrying from timing information...
\n
"
);
memcpy
(
vui
,
&
backup_vui
,
sizeof
(
backup_v
ui
));
memcpy
(
tVui
,
&
tBackupVui
,
sizeof
(
tBackupV
ui
));
memcpy
(
pvBuf
,
&
backup
,
sizeof
(
b
ackup
));
memcpy
(
pvBuf
,
&
tBackup
,
sizeof
(
tB
ackup
));
alt
=
1
;
alt
=
1
;
goto
timing_info
;
goto
timing_info
;
}
}
}
}
static
unsigned
avModUintp2c
(
unsigned
a
,
unsigned
p
)
{
return
a
&
((
1
<<
p
)
-
1
);
}
int
h265DecSeqParameterSet
(
void
*
pvBufSrc
,
T_HEVCSPS
*
s
ps
)
int
h265DecSeqParameterSet
(
void
*
pvBufSrc
,
T_HEVCSPS
*
ptS
ps
)
{
{
T_HEVCWindow
*
ow
;
T_HEVCWindow
*
ow
;
// int ret = 0;
int
iLog2DiffMaxMinTransformBlockSize
;
int
log2_diff_max_min_transform_block_size
;
int
iBitDepthChroma
,
iStart
,
iVuiPresent
,
iSublayerOrderingInfo
;
int
bit_depth_chroma
,
start
,
vui_present
,
sublayer_ordering_info
;
int
i
;
int
i
;
int
iRet
=
0
;
int
iRet
=
0
;
void
*
pvBuf
=
NULL
;
void
*
pvBuf
=
NULL
;
if
(
NULL
==
pvBufSrc
||
NULL
==
s
ps
)
if
(
NULL
==
pvBufSrc
||
NULL
==
ptS
ps
)
{
{
RPT
(
RPT_ERR
,
"ERR null pointer
\n
"
);
RPT
(
RPT_ERR
,
"ERR null pointer
\n
"
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
memset
((
void
*
)
s
ps
,
0
,
sizeof
(
T_HEVCSPS
));
memset
((
void
*
)
ptS
ps
,
0
,
sizeof
(
T_HEVCSPS
));
pvBuf
=
deEmulationPrevention
(
pvBufSrc
);
pvBuf
=
deEmulationPrevention
(
pvBufSrc
);
if
(
NULL
==
pvBuf
)
if
(
NULL
==
pvBuf
)
...
@@ -1716,35 +1695,26 @@ int h265DecSeqParameterSet( void *pvBufSrc, T_HEVCSPS *sps )
...
@@ -1716,35 +1695,26 @@ int h265DecSeqParameterSet( void *pvBufSrc, T_HEVCSPS *sps )
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
// Coded parameters
// Coded parameters
sps
->
vps_i
d
=
getBits
(
pvBuf
,
4
);
ptSps
->
uiVpsI
d
=
getBits
(
pvBuf
,
4
);
if
(
sps
->
vps_i
d
>=
HEVC_MAX_VPS_COUNT
)
{
if
(
ptSps
->
uiVpsI
d
>=
HEVC_MAX_VPS_COUNT
)
{
RPT
(
RPT_ERR
,
"VPS id out of range: %d
\n
"
,
sps
->
vps_i
d
);
RPT
(
RPT_ERR
,
"VPS id out of range: %d
\n
"
,
ptSps
->
uiVpsI
d
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
#if 0
ptSps
->
iMaxSubLayers
=
getBits
(
pvBuf
,
3
)
+
1
;
if (vps_list && !vps_list[sps->vps_id]) {
if
(
ptSps
->
iMaxSubLayers
>
HEVC_MAX_SUB_LAYERS
)
{
RPT(RPT_ERR, "VPS %d does not exist\n",
sps->vps_id);
return AVERROR_INVALIDDATA;
}
#endif
sps
->
max_sub_layers
=
getBits
(
pvBuf
,
3
)
+
1
;
if
(
sps
->
max_sub_layers
>
HEVC_MAX_SUB_LAYERS
)
{
RPT
(
RPT_ERR
,
"sps_max_sub_layers out of range: %d
\n
"
,
RPT
(
RPT_ERR
,
"sps_max_sub_layers out of range: %d
\n
"
,
sps
->
max_sub_l
ayers
);
ptSps
->
iMaxSubL
ayers
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
sps
->
temporal_id_nesting_f
lag
=
getBits
(
pvBuf
,
1
);
ptSps
->
u8temporalIdNestingF
lag
=
getBits
(
pvBuf
,
1
);
if
((
iRet
=
parsePtl
(
pvBuf
,
&
sps
->
ptl
,
sps
->
max_sub_l
ayers
))
<
0
)
if
((
iRet
=
parsePtl
(
pvBuf
,
&
ptSps
->
tPtl
,
ptSps
->
iMaxSubL
ayers
))
<
0
)
goto
exit
;
goto
exit
;
int
sps_id
=
parseUe
(
pvBuf
);
int
sps_id
=
parseUe
(
pvBuf
);
...
@@ -1754,320 +1724,290 @@ int h265DecSeqParameterSet( void *pvBufSrc, T_HEVCSPS *sps )
...
@@ -1754,320 +1724,290 @@ int h265DecSeqParameterSet( void *pvBufSrc, T_HEVCSPS *sps )
goto
exit
;
goto
exit
;
}
}
sps
->
chroma_format_i
dc
=
parseUe
(
pvBuf
);
ptSps
->
iChromaFormatI
dc
=
parseUe
(
pvBuf
);
if
(
sps
->
chroma_format_i
dc
>
3U
)
{
if
(
ptSps
->
iChromaFormatI
dc
>
3U
)
{
RPT
(
RPT_ERR
,
"
chroma_format_idc %d is invalid
\n
"
,
sps
->
chroma_format_i
dc
);
RPT
(
RPT_ERR
,
"
iChromaFormatIdc %d is invalid
\n
"
,
ptSps
->
iChromaFormatI
dc
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
if
(
sps
->
chroma_format_i
dc
==
3
)
if
(
ptSps
->
iChromaFormatI
dc
==
3
)
sps
->
separate_colour_plane_f
lag
=
getOneBit
(
pvBuf
);
ptSps
->
u8SeparateColourPlaneF
lag
=
getOneBit
(
pvBuf
);
if
(
sps
->
separate_colour_plane_f
lag
)
if
(
ptSps
->
u8SeparateColourPlaneF
lag
)
sps
->
chroma_format_i
dc
=
0
;
ptSps
->
iChromaFormatI
dc
=
0
;
sps
->
width
=
parseUe
(
pvBuf
);
ptSps
->
iWidth
=
parseUe
(
pvBuf
);
sps
->
height
=
parseUe
(
pvBuf
);
ptSps
->
iHeight
=
parseUe
(
pvBuf
);
// if ((iRet = av_image_check_size(sps->width,
// sps->height, 0, avctx)) < 0)
// goto exit;
if
(
getOneBit
(
pvBuf
))
{
// pic_conformance_flag
if
(
getOneBit
(
pvBuf
))
{
// pic_conformance_flag
int
vert_mult
=
hevc_sub_height_c
[
sps
->
chroma_format_i
dc
];
int
vert_mult
=
sg_au8HevcSubHeightC
[
ptSps
->
iChromaFormatI
dc
];
int
horiz_mult
=
hevc_sub_width_c
[
sps
->
chroma_format_i
dc
];
int
horiz_mult
=
sg_au8HevcSubWidthC
[
ptSps
->
iChromaFormatI
dc
];
sps
->
pic_conf_win
.
left_o
ffset
=
parseUe
(
pvBuf
)
*
horiz_mult
;
ptSps
->
tPicConfWin
.
uiLeftO
ffset
=
parseUe
(
pvBuf
)
*
horiz_mult
;
sps
->
pic_conf_win
.
right_o
ffset
=
parseUe
(
pvBuf
)
*
horiz_mult
;
ptSps
->
tPicConfWin
.
uiRightO
ffset
=
parseUe
(
pvBuf
)
*
horiz_mult
;
sps
->
pic_conf_win
.
top_o
ffset
=
parseUe
(
pvBuf
)
*
vert_mult
;
ptSps
->
tPicConfWin
.
uiTopO
ffset
=
parseUe
(
pvBuf
)
*
vert_mult
;
sps
->
pic_conf_win
.
bottom_o
ffset
=
parseUe
(
pvBuf
)
*
vert_mult
;
ptSps
->
tPicConfWin
.
uiBottomO
ffset
=
parseUe
(
pvBuf
)
*
vert_mult
;
sps
->
output_window
=
sps
->
pic_conf_w
in
;
ptSps
->
tOutputWindow
=
ptSps
->
tPicConfW
in
;
}
}
sps
->
bit_d
epth
=
parseUe
(
pvBuf
)
+
8
;
ptSps
->
iBitD
epth
=
parseUe
(
pvBuf
)
+
8
;
bit_depth_c
hroma
=
parseUe
(
pvBuf
)
+
8
;
iBitDepthC
hroma
=
parseUe
(
pvBuf
)
+
8
;
if
(
sps
->
chroma_format_idc
&&
bit_depth_chroma
!=
sps
->
bit_d
epth
)
{
if
(
ptSps
->
iChromaFormatIdc
&&
iBitDepthChroma
!=
ptSps
->
iBitD
epth
)
{
RPT
(
RPT_ERR
,
RPT
(
RPT_ERR
,
"Luma bit depth (%d) is different from chroma bit depth (%d), "
"Luma bit depth (%d) is different from chroma bit depth (%d), "
"this is unsupported.
\n
"
,
"this is unsupported.
\n
"
,
sps
->
bit_depth
,
bit_depth_c
hroma
);
ptSps
->
iBitDepth
,
iBitDepthC
hroma
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
sps
->
bit_depth_chroma
=
bit_depth_c
hroma
;
ptSps
->
iBitDepthChroma
=
iBitDepthC
hroma
;
#if 0
ptSps
->
uiLog2MaxPocLsb
=
parseUe
(
pvBuf
)
+
4
;
iRet = map_pixel_format(avctx, sps);
if
(
ptSps
->
uiLog2MaxPocLsb
>
16
)
{
if (iRet < 0)
goto exit;
#endif
#if 0
sps->log2_max_poc_lsb = parseUe(pvBuf) + 4;
if (sps->log2_max_poc_lsb > 16) {
RPT
(
RPT_ERR
,
"log2_max_pic_order_cnt_lsb_minus4 out range: %d
\n
"
,
RPT
(
RPT_ERR
,
"log2_max_pic_order_cnt_lsb_minus4 out range: %d
\n
"
,
sps->log2_max_poc_l
sb - 4);
ptSps
->
uiLog2MaxPocL
sb
-
4
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
sublayer_ordering_i
nfo = getOneBit(pvBuf);
iSublayerOrderingI
nfo
=
getOneBit
(
pvBuf
);
start = sublayer_ordering_info ? 0 : sps->max_sub_l
ayers - 1;
iStart
=
iSublayerOrderingInfo
?
0
:
ptSps
->
iMaxSubL
ayers
-
1
;
for (i =
start; i < sps->max_sub_l
ayers; i++) {
for
(
i
=
iStart
;
i
<
ptSps
->
iMaxSubL
ayers
;
i
++
)
{
sps->temporal_layer[i].max_dec_pic_b
uffering = parseUe(pvBuf) + 1;
ptSps
->
stTemporalLayer
[
i
].
iMaxDecPicB
uffering
=
parseUe
(
pvBuf
)
+
1
;
sps->temporal_layer[i].num_reorder_p
ics = parseUe(pvBuf);
ptSps
->
stTemporalLayer
[
i
].
iNumReorderP
ics
=
parseUe
(
pvBuf
);
sps->temporal_layer[i].max_latency_i
ncrease = parseUe(pvBuf) - 1;
ptSps
->
stTemporalLayer
[
i
].
iMaxLatencyI
ncrease
=
parseUe
(
pvBuf
)
-
1
;
if (
sps->temporal_layer[i].max_dec_pic_b
uffering > (unsigned)HEVC_MAX_DPB_SIZE) {
if
(
ptSps
->
stTemporalLayer
[
i
].
iMaxDecPicB
uffering
>
(
unsigned
)
HEVC_MAX_DPB_SIZE
)
{
RPT
(
RPT_ERR
,
"sps_max_dec_pic_buffering_minus1 out of range: %d
\n
"
,
RPT
(
RPT_ERR
,
"sps_max_dec_pic_buffering_minus1 out of range: %d
\n
"
,
sps->temporal_layer[i].max_dec_pic_b
uffering - 1U);
ptSps
->
stTemporalLayer
[
i
].
iMaxDecPicB
uffering
-
1U
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
if (
sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_b
uffering - 1) {
if
(
ptSps
->
stTemporalLayer
[
i
].
iNumReorderPics
>
ptSps
->
stTemporalLayer
[
i
].
iMaxDecPicB
uffering
-
1
)
{
RPT
(
RPT_WRN
,
"sps_max_num_reorder_pics out of range: %d
\n
"
,
RPT
(
RPT_WRN
,
"sps_max_num_reorder_pics out of range: %d
\n
"
,
sps->temporal_layer[i].num_reorder_p
ics);
ptSps
->
stTemporalLayer
[
i
].
iNumReorderP
ics
);
if (
sps->temporal_layer[i].num_reorder_p
ics > HEVC_MAX_DPB_SIZE - 1) {
if
(
ptSps
->
stTemporalLayer
[
i
].
iNumReorderP
ics
>
HEVC_MAX_DPB_SIZE
-
1
)
{
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[i].num_reorder_p
ics + 1;
ptSps
->
stTemporalLayer
[
i
].
iMaxDecPicBuffering
=
ptSps
->
stTemporalLayer
[
i
].
iNumReorderP
ics
+
1
;
}
}
}
}
if (!
sublayer_ordering_i
nfo) {
if
(
!
iSublayerOrderingI
nfo
)
{
for (i = 0; i <
s
tart; i++) {
for
(
i
=
0
;
i
<
iS
tart
;
i
++
)
{
sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[start].max_dec_pic_b
uffering;
ptSps
->
stTemporalLayer
[
i
].
iMaxDecPicBuffering
=
ptSps
->
stTemporalLayer
[
iStart
].
iMaxDecPicB
uffering
;
sps->temporal_layer[i].num_reorder_pics = sps->temporal_layer[start].num_reorder_p
ics;
ptSps
->
stTemporalLayer
[
i
].
iNumReorderPics
=
ptSps
->
stTemporalLayer
[
iStart
].
iNumReorderP
ics
;
sps->temporal_layer[i].max_latency_increase = sps->temporal_layer[start].max_latency_i
ncrease;
ptSps
->
stTemporalLayer
[
i
].
iMaxLatencyIncrease
=
ptSps
->
stTemporalLayer
[
iStart
].
iMaxLatencyI
ncrease
;
}
}
}
}
sps->log2_min_cb_s
ize = parseUe(pvBuf) + 3;
ptSps
->
uiLog2MinCbS
ize
=
parseUe
(
pvBuf
)
+
3
;
sps->log2_diff_max_min_coding_block_size
= parseUe(pvBuf);
ptSps
->
uiLog2DiffMaxMinCodingBlockSize
=
parseUe
(
pvBuf
);
sps->log2_min_tb_s
ize = parseUe(pvBuf) + 2;
ptSps
->
uiLog2MinTbS
ize
=
parseUe
(
pvBuf
)
+
2
;
log2_diff_max_min_transform_block_size
= parseUe(pvBuf);
iLog2DiffMaxMinTransformBlockSize
=
parseUe
(
pvBuf
);
sps->log2_max_trafo_size = log2_diff_max_min_transform_block_s
ize +
ptSps
->
uiLog2MaxTrafoSize
=
iLog2DiffMaxMinTransformBlockS
ize
+
sps->log2_min_tb_s
ize;
ptSps
->
uiLog2MinTbS
ize
;
if (
sps->log2_min_cb_size < 3 || sps->log2_min_cb_s
ize > 30) {
if
(
ptSps
->
uiLog2MinCbSize
<
3
||
ptSps
->
uiLog2MinCbS
ize
>
30
)
{
RPT(RPT_ERR, "Invalid value %d for
log2_min_cb_size", sps->log2_min_cb_s
ize);
RPT
(
RPT_ERR
,
"Invalid value %d for
uiLog2MinCbSize"
,
ptSps
->
uiLog2MinCbS
ize
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
if (
sps->log2_diff_max_min_coding_block_s
ize > 30) {
if
(
ptSps
->
uiLog2DiffMaxMinCodingBlockS
ize
>
30
)
{
RPT(RPT_ERR, "Invalid value %d for
log2_diff_max_min_coding_block_size", sps->log2_diff_max_min_coding_block_s
ize);
RPT
(
RPT_ERR
,
"Invalid value %d for
uiLog2DiffMaxMinCodingBlockSize"
,
ptSps
->
uiLog2DiffMaxMinCodingBlockS
ize
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
if (
sps->log2_min_tb_size >= sps->log2_min_cb_size || sps->log2_min_tb_s
ize < 2) {
if
(
ptSps
->
uiLog2MinTbSize
>=
ptSps
->
uiLog2MinCbSize
||
ptSps
->
uiLog2MinTbS
ize
<
2
)
{
RPT(RPT_ERR, "Invalid value for
log2_min_tb_s
ize");
RPT
(
RPT_ERR
,
"Invalid value for
uiLog2MinTbS
ize"
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
if (
log2_diff_max_min_transform_block_size < 0 || log2_diff_max_min_transform_block_s
ize > 30) {
if
(
iLog2DiffMaxMinTransformBlockSize
<
0
||
iLog2DiffMaxMinTransformBlockS
ize
>
30
)
{
RPT(RPT_ERR, "Invalid value %d for
log2_diff_max_min_transform_block_size", log2_diff_max_min_transform_block_s
ize);
RPT
(
RPT_ERR
,
"Invalid value %d for
iLog2DiffMaxMinTransformBlockSize"
,
iLog2DiffMaxMinTransformBlockS
ize
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
sps->max_transform_hierarchy_depth_inter = parseUe(pvBuf);
ptSps
->
iMaxTransformHierarchyDepthInter
=
parseUe
(
pvBuf
);
sps->max_transform_hierarchy_depth_intra = parseUe(pvBuf);
ptSps
->
iMaxTransformHierarchyDepthIntra
=
parseUe
(
pvBuf
);
sps->scaling_list_enable_flag = getOneBit(pvBuf);
printf("sps->scaling_list_enable_flag: %d\n",sps->scaling_list_enable_flag
);
ptSps
->
u8ScalingListEnableFlag
=
getOneBit
(
pvBuf
);
if (
sps->scaling_list_enable_f
lag) {
if
(
ptSps
->
u8ScalingListEnableF
lag
)
{
setDefaultScalingListData(&
sps->scaling_l
ist);
setDefaultScalingListData
(
&
ptSps
->
tScalingL
ist
);
if
(
getOneBit
(
pvBuf
))
{
if
(
getOneBit
(
pvBuf
))
{
iRet = scalingListData(pvBuf, &
sps->scaling_list, s
ps);
iRet
=
scalingListData
(
pvBuf
,
&
ptSps
->
tScalingList
,
ptS
ps
);
if
(
iRet
<
0
)
if
(
iRet
<
0
)
goto
exit
;
goto
exit
;
}
}
}
}
sps->amp_enabled_f
lag = getOneBit(pvBuf);
ptSps
->
u8AmpEnabledF
lag
=
getOneBit
(
pvBuf
);
sps->sao_e
nabled = getOneBit(pvBuf);
ptSps
->
u8SaoE
nabled
=
getOneBit
(
pvBuf
);
sps->pcm_enabled_f
lag = getOneBit(pvBuf);
ptSps
->
iPcmEnabledF
lag
=
getOneBit
(
pvBuf
);
printf("sps->pcm_enabled_flag: %d\n",sps->pcm_enabled_flag);
if
(
ptSps
->
iPcmEnabledFlag
)
{
if (sps->pcm_enabled_flag) {
ptSps
->
pcm
.
u8BitDepth
=
getBits
(
pvBuf
,
4
)
+
1
;
sps->pcm.bit_depth = getBits(pvBuf, 4) + 1;
ptSps
->
pcm
.
u8BitDepthChroma
=
getBits
(
pvBuf
,
4
)
+
1
;
sps->pcm.bit_depth_chroma = getBits(pvBuf, 4) + 1;
ptSps
->
pcm
.
uiLog2MinPcmCbSize
=
parseUe
(
pvBuf
)
+
3
;
sps->pcm.log2_min_pcm_cb_size = parseUe(pvBuf) + 3;
ptSps
->
pcm
.
uiLog2MaxPcmCbSize
=
ptSps
->
pcm
.
uiLog2MinPcmCbSize
+
sps->pcm.log2_max_pcm_cb_size = sps->pcm.log2_min_pcm_cb_size +
parseUe
(
pvBuf
);
parseUe
(
pvBuf
);
if (FFMAX(
sps->pcm.bit_depth, sps->pcm.bit_depth_chroma) > sps->bit_d
epth) {
if
(
FFMAX
(
ptSps
->
pcm
.
u8BitDepth
,
ptSps
->
pcm
.
u8BitDepthChroma
)
>
ptSps
->
iBitD
epth
)
{
RPT
(
RPT_ERR
,
RPT
(
RPT_ERR
,
"PCM bit depth (%d, %d) is greater than normal bit depth (%d)
\n
"
,
"PCM bit depth (%d, %d) is greater than normal bit depth (%d)
\n
"
,
sps->pcm.bit_depth, sps->pcm.bit_depth_chroma, sps->bit_d
epth);
ptSps
->
pcm
.
u8BitDepth
,
ptSps
->
pcm
.
u8BitDepthChroma
,
ptSps
->
iBitD
epth
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
sps->pcm.loop_filter_disable_f
lag = getOneBit(pvBuf);
ptSps
->
pcm
.
u8LoopFilterDisableF
lag
=
getOneBit
(
pvBuf
);
}
}
sps->nb_st_r
ps = parseUe(pvBuf);
ptSps
->
uiNbStR
ps
=
parseUe
(
pvBuf
);
if (
sps->nb_st_r
ps > HEVC_MAX_SHORT_TERM_REF_PIC_SETS) {
if
(
ptSps
->
uiNbStR
ps
>
HEVC_MAX_SHORT_TERM_REF_PIC_SETS
)
{
RPT
(
RPT_ERR
,
"Too many short term RPS: %d.
\n
"
,
RPT
(
RPT_ERR
,
"Too many short term RPS: %d.
\n
"
,
sps->nb_st_r
ps);
ptSps
->
uiNbStR
ps
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
printf("sps->nb_st_rps: %d\n",sps->nb_st_rps);
for
(
i
=
0
;
i
<
ptSps
->
uiNbStRps
;
i
++
)
{
for (i = 0; i < sps->nb_st_rps; i++) {
if
((
iRet
=
hevcDecodeShortTermRps
(
pvBuf
,
&
ptSps
->
atStRps
[
i
],
if ((iRet = hevcDecodeShortTermRps(pvBuf, &sps->st_rps[i],
ptSps
,
0
))
<
0
)
sps, 0)) < 0)
goto
exit
;
goto
exit
;
}
}
sps->long_term_ref_pics_present_f
lag = getOneBit(pvBuf);
ptSps
->
u8LongTermRefPicsPresentF
lag
=
getOneBit
(
pvBuf
);
if (
sps->long_term_ref_pics_present_f
lag) {
if
(
ptSps
->
u8LongTermRefPicsPresentF
lag
)
{
sps->num_long_term_ref_pics_s
ps = parseUe(pvBuf);
ptSps
->
u8NumLongTermRefPicsS
ps
=
parseUe
(
pvBuf
);
if (
sps->num_long_term_ref_pics_s
ps > HEVC_MAX_LONG_TERM_REF_PICS) {
if
(
ptSps
->
u8NumLongTermRefPicsS
ps
>
HEVC_MAX_LONG_TERM_REF_PICS
)
{
RPT
(
RPT_ERR
,
"Too many long term ref pics: %d.
\n
"
,
RPT
(
RPT_ERR
,
"Too many long term ref pics: %d.
\n
"
,
sps->num_long_term_ref_pics_s
ps);
ptSps
->
u8NumLongTermRefPicsS
ps
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
for (i = 0; i <
sps->num_long_term_ref_pics_s
ps; i++) {
for
(
i
=
0
;
i
<
ptSps
->
u8NumLongTermRefPicsS
ps
;
i
++
)
{
sps->lt_ref_pic_poc_lsb_sps[i] = getBits(pvBuf, sps->log2_max_poc_l
sb);
ptSps
->
au16LtRefPicPocLsbSps
[
i
]
=
getBits
(
pvBuf
,
ptSps
->
uiLog2MaxPocL
sb
);
sps->used_by_curr_pic_lt_sps_f
lag[i] = getOneBit(pvBuf);
ptSps
->
au8UsedByCurrPicLtSpsF
lag
[
i
]
=
getOneBit
(
pvBuf
);
}
}
}
}
sps->sps_temporal_mvp_enabled_flag = getOneBit(pvBuf);
ptSps
->
u8SpsTemporalMvpEnabledFlag
=
getOneBit
(
pvBuf
);
sps->sps_strong_intra_smoothing_enable_flag = getOneBit(pvBuf);
ptSps
->
u8SpsStrongIntraMmoothingEnableFlag
=
getOneBit
(
pvBuf
);
sps->vui.sar = (T_AVRational){0, 1};
ptSps
->
tVui
.
tSar
=
(
T_AVRational
){
0
,
1
};
vui_present = getOneBit(pvBuf);
ptSps
->
iVuiPresent
=
getOneBit
(
pvBuf
);
if (vui_present==1)
if
(
ptSps
->
iVuiPresent
)
decodeVui(pvBuf, sps);
decodeVui
(
pvBuf
,
ptSps
);
#endif
#if 0
if
(
getOneBit
(
pvBuf
))
{
// sps_extension_flag
if
(
getOneBit
(
pvBuf
))
{
// sps_extension_flag
int
sps_range_extension_f
lag = getOneBit(pvBuf);
int
iSpsRangeExtensionF
lag
=
getOneBit
(
pvBuf
);
getBits
(
pvBuf
,
7
);
//sps_extension_7bits = getBits(pvBuf, 7);
getBits
(
pvBuf
,
7
);
//sps_extension_7bits = getBits(pvBuf, 7);
if (
sps_range_extension_f
lag) {
if
(
iSpsRangeExtensionF
lag
)
{
int
extended_precision_processing_f
lag;
int
iExtendedPrecisionProcessingF
lag
;
int
cabac_bypass_alignment_enabled_f
lag;
int
iCabacBypassAlignmentEnabledF
lag
;
sps->transform_skip_rotation_enabled_f
lag = getOneBit(pvBuf);
ptSps
->
iTransformSkipRotationEnabledF
lag
=
getOneBit
(
pvBuf
);
sps->transform_skip_context_enabled_f
lag = getOneBit(pvBuf);
ptSps
->
iTransformSkipContextEnabledF
lag
=
getOneBit
(
pvBuf
);
sps->implicit_rdpcm_enabled_f
lag = getOneBit(pvBuf);
ptSps
->
iImplicitRdpcmEnabledF
lag
=
getOneBit
(
pvBuf
);
sps->explicit_rdpcm_enabled_f
lag = getOneBit(pvBuf);
ptSps
->
iExplicitRdpcmEnabledF
lag
=
getOneBit
(
pvBuf
);
extended_precision_processing_f
lag = getOneBit(pvBuf);
iExtendedPrecisionProcessingF
lag
=
getOneBit
(
pvBuf
);
if (
extended_precision_processing_f
lag)
if
(
iExtendedPrecisionProcessingF
lag
)
RPT
(
RPT_WRN
,
RPT
(
RPT_WRN
,
"
extended_precision_processing_f
lag not yet implemented\n");
"
iExtendedPrecisionProcessingF
lag not yet implemented
\n
"
);
sps->intra_smoothing_disabled_f
lag = getOneBit(pvBuf);
ptSps
->
iIntraSmoothingDisabledF
lag
=
getOneBit
(
pvBuf
);
sps->high_precision_offsets_enabled_f
lag = getOneBit(pvBuf);
ptSps
->
iHighPrecisionOffsetsEnabledF
lag
=
getOneBit
(
pvBuf
);
if (
sps->high_precision_offsets_enabled_f
lag)
if
(
ptSps
->
iHighPrecisionOffsetsEnabledF
lag
)
RPT
(
RPT_WRN
,
RPT
(
RPT_WRN
,
"
high_precision_offsets_enabled_f
lag not yet implemented\n");
"
iHighPrecisionOffsetsEnabledF
lag not yet implemented
\n
"
);
sps->persistent_rice_adaptation_enabled_f
lag = getOneBit(pvBuf);
ptSps
->
iPersistentRiceAdaptationEnabledF
lag
=
getOneBit
(
pvBuf
);
cabac_bypass_alignment_enabled_f
lag = getOneBit(pvBuf);
iCabacBypassAlignmentEnabledF
lag
=
getOneBit
(
pvBuf
);
if (
cabac_bypass_alignment_enabled_f
lag)
if
(
iCabacBypassAlignmentEnabledF
lag
)
RPT
(
RPT_WRN
,
RPT
(
RPT_WRN
,
"
cabac_bypass_alignment_enabled_f
lag not yet implemented\n");
"
iCabacBypassAlignmentEnabledF
lag not yet implemented
\n
"
);
}
}
}
}
if (apply_defdispwin) {
sps->output_window.left_offset += sps->vui.def_disp_win.left_offset;
sps->output_window.right_offset += sps->vui.def_disp_win.right_offset;
sps->output_window.top_offset += sps->vui.def_disp_win.top_offset;
sps->output_window.bottom_offset += sps->vui.def_disp_win.bottom_offset;
}
ow = &
sps->output_w
indow;
ow
=
&
ptSps
->
tOutputW
indow
;
if (ow->
left_offset >= INT_MAX - ow->right_o
ffset ||
if
(
ow
->
uiLeftOffset
>=
INT_MAX
-
ow
->
uiRightO
ffset
||
ow->
top_offset >= INT_MAX - ow->bottom_o
ffset ||
ow
->
uiTopOffset
>=
INT_MAX
-
ow
->
uiBottomO
ffset
||
ow->
left_offset + ow->right_offset >= sps->w
idth ||
ow
->
uiLeftOffset
+
ow
->
uiRightOffset
>=
ptSps
->
iW
idth
||
ow->
top_offset + ow->bottom_offset >= sps->h
eight) {
ow
->
uiTopOffset
+
ow
->
uiBottomOffset
>=
ptSps
->
iH
eight
)
{
RPT
(
RPT_WRN
,
"Invalid cropping offsets: %u/%u/%u/%u
\n
"
,
RPT
(
RPT_WRN
,
"Invalid cropping offsets: %u/%u/%u/%u
\n
"
,
ow->left_offset, ow->right_offset, ow->top_offset, ow->bottom_offset);
ow
->
uiLeftOffset
,
ow
->
uiRightOffset
,
ow
->
uiTopOffset
,
ow
->
uiBottomOffset
);
if (avctx->err_recognition & AV_EF_EXPLODE) {
return AVERROR_INVALIDDATA;
}
RPT
(
RPT_WRN
,
RPT
(
RPT_WRN
,
"Displaying the whole video surface.
\n
"
);
"Displaying the whole video surface.
\n
"
);
memset
(
ow
,
0
,
sizeof
(
*
ow
));
memset
(
ow
,
0
,
sizeof
(
*
ow
));
memset(&
sps->pic_conf_win, 0, sizeof(sps->pic_conf_w
in));
memset
(
&
ptSps
->
tPicConfWin
,
0
,
sizeof
(
ptSps
->
tPicConfW
in
));
}
}
// Inferred parameters
// Inferred parameters
sps->log2_ctb_size = sps->log2_min_cb_s
ize +
ptSps
->
uiLog2CtbSize
=
ptSps
->
uiLog2MinCbS
ize
+
sps->log2_diff_max_min_coding_block_s
ize;
ptSps
->
uiLog2DiffMaxMinCodingBlockS
ize
;
sps->log2_min_pu_size = sps->log2_min_cb_s
ize - 1;
ptSps
->
uiLog2MinPuSize
=
ptSps
->
uiLog2MinCbS
ize
-
1
;
if (sps->log2_ctb_size > HEVC_MAX_LOG2_CTB_SIZE) {
if
(
ptSps
->
uiLog2CtbSize
>
HEVC_MAX_LOG2_CTB_SIZE
)
{
RPT(RPT_ERR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size);
RPT
(
RPT_ERR
,
"CTB size out of range: 2^%d
\n
"
,
ptSps
->
uiLog2CtbSize
);
iRet = -1;
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
if (
sps->log2_ctb_s
ize < 4) {
if
(
ptSps
->
uiLog2CtbS
ize
<
4
)
{
RPT
(
RPT_ERR
,
RPT
(
RPT_ERR
,
"log2_ctb_size %d differs from the bounds of any known profile\n",
"uiLog2CtbSize %d differs from the bounds of any known profile
\n
"
,
sps->log2_ctb_size);
ptSps
->
uiLog2CtbSize
);
avpriv_request_sample(avctx, "log2_ctb_size %d", sps->log2_ctb_size);
iRet = -1;
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
sps->ctb_width = (sps->width + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_s
ize;
ptSps
->
iCtbWidth
=
(
ptSps
->
iWidth
+
(
1
<<
ptSps
->
uiLog2CtbSize
)
-
1
)
>>
ptSps
->
uiLog2CtbS
ize
;
sps->ctb_height = (sps->height + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_s
ize;
ptSps
->
iCtbHeight
=
(
ptSps
->
iHeight
+
(
1
<<
ptSps
->
uiLog2CtbSize
)
-
1
)
>>
ptSps
->
uiLog2CtbS
ize
;
sps->ctb_size = sps->ctb_width * sps->ctb_h
eight;
ptSps
->
iCtbSize
=
ptSps
->
iCtbWidth
*
ptSps
->
iCtbH
eight
;
sps->min_cb_width = sps->width >> sps->log2_min_cb_s
ize;
ptSps
->
iMinCbWidth
=
ptSps
->
iWidth
>>
ptSps
->
uiLog2MinCbS
ize
;
sps->min_cb_height = sps->height >> sps->log2_min_cb_s
ize;
ptSps
->
iMinCbHeight
=
ptSps
->
iHeight
>>
ptSps
->
uiLog2MinCbS
ize
;
sps->min_tb_width = sps->width >> sps->log2_min_tb_s
ize;
ptSps
->
iMinTbWidth
=
ptSps
->
iWidth
>>
ptSps
->
uiLog2MinTbS
ize
;
sps->min_tb_height = sps->height >> sps->log2_min_tb_s
ize;
ptSps
->
iMinTbHeight
=
ptSps
->
iHeight
>>
ptSps
->
uiLog2MinTbS
ize
;
sps->min_pu_width = sps->width >> sps->log2_min_pu_s
ize;
ptSps
->
iMinPuWidth
=
ptSps
->
iWidth
>>
ptSps
->
uiLog2MinPuS
ize
;
sps->min_pu_height = sps->height >> sps->log2_min_pu_s
ize;
ptSps
->
iMinPuHeight
=
ptSps
->
iHeight
>>
ptSps
->
uiLog2MinPuS
ize
;
sps->tb_mask = (1 << (sps->log2_ctb_size - sps->log2_min_tb_s
ize)) - 1;
ptSps
->
iTbMask
=
(
1
<<
(
ptSps
->
uiLog2CtbSize
-
ptSps
->
uiLog2MinTbS
ize
))
-
1
;
sps->qp_bd_offset = 6 * (sps->bit_d
epth - 8);
ptSps
->
iQpBdOffset
=
6
*
(
ptSps
->
iBitD
epth
-
8
);
if (av
_mod_uintp2(sps->width, sps->log2_min_cb_s
ize) ||
if
(
av
ModUintp2c
(
ptSps
->
iWidth
,
ptSps
->
uiLog2MinCbS
ize
)
||
av
_mod_uintp2(sps->height, sps->log2_min_cb_s
ize)) {
av
ModUintp2c
(
ptSps
->
iHeight
,
ptSps
->
uiLog2MinCbS
ize
))
{
RPT
(
RPT_ERR
,
"Invalid coded frame dimensions.
\n
"
);
RPT
(
RPT_ERR
,
"Invalid coded frame dimensions.
\n
"
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
if (
sps->max_transform_hierarchy_depth_inter > sps->log2_ctb_size - sps->log2_min_tb_s
ize) {
if
(
ptSps
->
iMaxTransformHierarchyDepthInter
>
ptSps
->
uiLog2CtbSize
-
ptSps
->
uiLog2MinTbS
ize
)
{
RPT(RPT_ERR, "
max_transform_hierarchy_depth_i
nter out of range: %d\n",
RPT
(
RPT_ERR
,
"
iMaxTransformHierarchyDepthI
nter out of range: %d
\n
"
,
sps->max_transform_hierarchy_depth_i
nter);
ptSps
->
iMaxTransformHierarchyDepthI
nter
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
if (
sps->max_transform_hierarchy_depth_intra > sps->log2_ctb_size - sps->log2_min_tb_s
ize) {
if
(
ptSps
->
iMaxTransformHierarchyDepthIntra
>
ptSps
->
uiLog2CtbSize
-
ptSps
->
uiLog2MinTbS
ize
)
{
RPT(RPT_ERR, "
max_transform_hierarchy_depth_i
ntra out of range: %d\n",
RPT
(
RPT_ERR
,
"
iMaxTransformHierarchyDepthI
ntra out of range: %d
\n
"
,
sps->max_transform_hierarchy_depth_i
ntra);
ptSps
->
iMaxTransformHierarchyDepthI
ntra
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
if (
sps->log2_max_trafo_size > FFMIN(sps->log2_ctb_s
ize, 5)) {
if
(
ptSps
->
uiLog2MaxTrafoSize
>
FFMIN
(
ptSps
->
uiLog2CtbS
ize
,
5
))
{
RPT
(
RPT_ERR
,
RPT
(
RPT_ERR
,
"max transform block size out of range: %d
\n
"
,
"max transform block size out of range: %d
\n
"
,
sps->log2_max_trafo_s
ize);
ptSps
->
uiLog2MaxTrafoS
ize
);
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
...
@@ -2078,7 +2018,6 @@ int h265DecSeqParameterSet( void *pvBufSrc, T_HEVCSPS *sps )
...
@@ -2078,7 +2018,6 @@ int h265DecSeqParameterSet( void *pvBufSrc, T_HEVCSPS *sps )
iRet
=
-
1
;
iRet
=
-
1
;
goto
exit
;
goto
exit
;
}
}
#endif
exit:
exit:
...
@@ -2088,6 +2027,141 @@ exit:
...
@@ -2088,6 +2027,141 @@ exit:
}
}
int
h265DecVideoParameterSet
(
void
*
pvBufSrc
,
T_HEVCVPS
*
ptVps
)
{
int
iRet
=
0
;
int
i
,
j
;
int
uiVpsId
=
0
;
void
*
pvBuf
=
NULL
;
if
(
NULL
==
pvBufSrc
||
NULL
==
ptVps
)
{
RPT
(
RPT_ERR
,
"ERR null pointer
\n
"
);
iRet
=
-
1
;
goto
exit
;
}
memset
((
void
*
)
ptVps
,
0
,
sizeof
(
T_HEVCVPS
));
pvBuf
=
deEmulationPrevention
(
pvBufSrc
);
if
(
NULL
==
pvBuf
)
{
RPT
(
RPT_ERR
,
"ERR null pointer
\n
"
);
iRet
=
-
1
;
goto
exit
;
}
RPT
(
RPT_DBG
,
"Decoding VPS
\n
"
);
uiVpsId
=
getBits
(
pvBuf
,
4
);
if
(
uiVpsId
>=
HEVC_MAX_VPS_COUNT
)
{
RPT
(
RPT_ERR
,
"VPS id out of range: %d
\n
"
,
uiVpsId
);
iRet
=
-
1
;
goto
exit
;
}
if
(
getBits
(
pvBuf
,
2
)
!=
3
)
{
// vps_reserved_three_2bits
RPT
(
RPT_ERR
,
"vps_reserved_three_2bits is not three
\n
"
);
iRet
=
-
1
;
goto
exit
;
}
ptVps
->
iVpsMaxLayers
=
getBits
(
pvBuf
,
6
)
+
1
;
ptVps
->
iVpsMaxSubLayers
=
getBits
(
pvBuf
,
3
)
+
1
;
ptVps
->
u8VpsTemporalIdNestingFlag
=
getOneBit
(
pvBuf
);
if
(
getBits
(
pvBuf
,
16
)
!=
0xffff
)
{
// vps_reserved_ffff_16bits
RPT
(
RPT_ERR
,
"vps_reserved_ffff_16bits is not 0xffff
\n
"
);
iRet
=
-
1
;
goto
exit
;
}
if
(
ptVps
->
iVpsMaxSubLayers
>
HEVC_MAX_SUB_LAYERS
)
{
RPT
(
RPT_ERR
,
"iVpsMaxSubLayers out of range: %d
\n
"
,
ptVps
->
iVpsMaxSubLayers
);
iRet
=
-
1
;
goto
exit
;
}
if
(
parsePtl
(
pvBuf
,
&
ptVps
->
tPtl
,
ptVps
->
iVpsMaxSubLayers
)
<
0
){
iRet
=
-
1
;
goto
exit
;
}
ptVps
->
iVpsSubLayerOrderingInfoPresentFlag
=
getOneBit
(
pvBuf
);
i
=
ptVps
->
iVpsSubLayerOrderingInfoPresentFlag
?
0
:
ptVps
->
iVpsMaxSubLayers
-
1
;
for
(;
i
<
ptVps
->
iVpsMaxSubLayers
;
i
++
)
{
ptVps
->
uiVpsMaxDecPicBuffering
[
i
]
=
parseUe
(
pvBuf
)
+
1
;
ptVps
->
auiVpsNumReorderPics
[
i
]
=
parseUe
(
pvBuf
);
ptVps
->
auiVpsMaxLatencyIncrease
[
i
]
=
parseUe
(
pvBuf
)
-
1
;
if
(
ptVps
->
uiVpsMaxDecPicBuffering
[
i
]
>
HEVC_MAX_DPB_SIZE
||
!
ptVps
->
uiVpsMaxDecPicBuffering
[
i
])
{
RPT
(
RPT_ERR
,
"vps_max_dec_pic_buffering_minus1 out of range: %d
\n
"
,
ptVps
->
uiVpsMaxDecPicBuffering
[
i
]
-
1
);
iRet
=
-
1
;
goto
exit
;
}
if
(
ptVps
->
auiVpsNumReorderPics
[
i
]
>
ptVps
->
uiVpsMaxDecPicBuffering
[
i
]
-
1
)
{
RPT
(
RPT_WRN
,
"vps_max_num_reorder_pics out of range: %d
\n
"
,
ptVps
->
auiVpsNumReorderPics
[
i
]);
}
}
ptVps
->
iVpsMaxLayerId
=
getBits
(
pvBuf
,
6
);
ptVps
->
iVpsNumLayerSets
=
parseUe
(
pvBuf
)
+
1
;
if
(
ptVps
->
iVpsNumLayerSets
<
1
||
ptVps
->
iVpsNumLayerSets
>
1024
||
(
ptVps
->
iVpsNumLayerSets
-
1LL
)
*
(
ptVps
->
iVpsMaxLayerId
+
1LL
)
>
getBitsLeft
(
pvBuf
))
{
RPT
(
RPT_ERR
,
"too many layer_id_included_flags
\n
"
);
iRet
=
-
1
;
goto
exit
;
}
for
(
i
=
1
;
i
<
ptVps
->
iVpsNumLayerSets
;
i
++
)
for
(
j
=
0
;
j
<=
ptVps
->
iVpsMaxLayerId
;
j
++
)
getBits
(
pvBuf
,
1
);
// layer_id_included_flag[i][j]
ptVps
->
u8VpsTimingInfoPresentFlag
=
getOneBit
(
pvBuf
);
if
(
ptVps
->
u8VpsTimingInfoPresentFlag
)
{
ptVps
->
u32VpsNumUnitsInTick
=
getBits
(
pvBuf
,
32
);
ptVps
->
u32VpsTimeScale
=
getBits
(
pvBuf
,
32
);
ptVps
->
u8VpsPocProportionalToTimingFlag
=
getOneBit
(
pvBuf
);
if
(
ptVps
->
u8VpsPocProportionalToTimingFlag
)
ptVps
->
iVpsNumTicksPocDiffOne
=
parseUe
(
pvBuf
)
+
1
;
ptVps
->
iVpsNumHrdParameters
=
parseUe
(
pvBuf
);
if
(
ptVps
->
iVpsNumHrdParameters
>
(
unsigned
)
ptVps
->
iVpsNumLayerSets
)
{
RPT
(
RPT_ERR
,
"iVpsNumHrdParameters %d is invalid
\n
"
,
ptVps
->
iVpsNumHrdParameters
);
iRet
=
-
1
;
goto
exit
;
}
for
(
i
=
0
;
i
<
ptVps
->
iVpsNumHrdParameters
;
i
++
)
{
int
common_inf_present
=
1
;
parseUe
(
pvBuf
);
// hrd_layer_set_idx
if
(
i
)
common_inf_present
=
getOneBit
(
pvBuf
);
decodeHrd
(
pvBuf
,
common_inf_present
,
ptVps
->
iVpsMaxSubLayers
);
}
}
getOneBit
(
pvBuf
);
/* vps_extension_flag */
if
(
getBitsLeft
(
pvBuf
)
<
0
)
{
RPT
(
RPT_ERR
,
"Overread VPS by %d bits
\n
"
,
-
getBitsLeft
(
pvBuf
));
iRet
=
-
1
;
goto
exit
;
}
exit:
getBitContextFree
(
pvBuf
);
return
iRet
;
}
void
h264GetWidthHeight
(
T_SPS
*
ptSps
,
int
*
piWidth
,
int
*
piHeight
)
void
h264GetWidthHeight
(
T_SPS
*
ptSps
,
int
*
piWidth
,
int
*
piHeight
)
{
{
...
@@ -2191,28 +2265,39 @@ void h264GeFramerate(T_SPS *ptSps, float *pfFramerate)
...
@@ -2191,28 +2265,39 @@ void h264GeFramerate(T_SPS *ptSps, float *pfFramerate)
void
h265GetWidthHeight
(
T_HEVCSPS
*
ptSps
,
int
*
piWidth
,
int
*
piHeight
)
void
h265GetWidthHeight
(
T_HEVCSPS
*
ptSps
,
int
*
piWidth
,
int
*
piHeight
)
{
{
#if 1
#if 1
// ¿í¸ß¼ÆË㹫ʽ
int
iCodeWidth
=
0
;
int
iCodeWidth
=
0
;
int
iCodedHeight
=
0
;
int
iCodedHeight
=
0
;
iCodeWidth
=
ptSps
->
width
;
iCodeWidth
=
ptSps
->
iWidth
;
iCodedHeight
=
ptSps
->
height
;
iCodedHeight
=
ptSps
->
iHeight
;
*
piWidth
=
ptSps
->
width
-
ptSps
->
pic_conf_win
.
left_offset
-
ptSps
->
pic_conf_win
.
right_offset
;
*
piWidth
=
ptSps
->
iWidth
-
ptSps
->
tOutputWindow
.
uiLeftOffset
-
ptSps
->
tOutputWindow
.
uiRightOffset
;
*
piHeight
=
ptSps
->
height
-
ptSps
->
pic_conf_win
.
top_offset
-
ptSps
->
pic_conf_win
.
bottom_offset
;
*
piHeight
=
ptSps
->
iHeight
-
ptSps
->
tOutputWindow
.
uiTopOffset
-
ptSps
->
tOutputWindow
.
uiBottomOffset
;
RPT
(
RPT_DBG
,
"iCodeWidth:%d, iCodedHeight:%d
\n
"
,
iCodeWidth
,
iCodedHeight
);
RPT
(
RPT_DBG
,
"iCodeWidth:%d, iCodedHeight:%d
\n
"
,
iCodeWidth
,
iCodedHeight
);
RPT
(
RPT_DBG
,
"*piWidth:%d, *piHeight:%d
\n
"
,
*
piWidth
,
*
piHeight
);
RPT
(
RPT_DBG
,
"*piWidth:%d, *piHeight:%d
\n
"
,
*
piWidth
,
*
piHeight
);
// RPT(RPT_DBG, "ptSps->uiCropRight:%d, ptSps->uiCropLeft:%d\n", ptSps->uiCropRight, ptSps->uiCropLef
t);
RPT
(
RPT_DBG
,
"ptSps->tOutputWindow.uiRightOffset:%d, ptSps->tOutputWindow.uiLeftOffset:%d
\n
"
,
ptSps
->
tOutputWindow
.
uiRightOffset
,
ptSps
->
tOutputWindow
.
uiLeftOffse
t
);
// RPT(RPT_DBG, "ptSps->uiCropTop:%d, ptSps->uiCropBottom:%d\n", ptSps->uiCropTop, ptSps->uiCropBottom
);
RPT
(
RPT_DBG
,
"ptSps->tOutputWindow.uiTopOffset:%d, ptSps->tOutputWindow.uiBottomOffset:%d
\n
"
,
ptSps
->
tOutputWindow
.
uiTopOffset
,
ptSps
->
tOutputWindow
.
uiBottomOffset
);
#endif
#endif
}
}
void
h265GeFramerate
(
T_HEVC
SPS
*
ptSps
,
float
*
pfFramerate
)
void
h265GeFramerate
(
T_HEVC
VPS
*
ptVps
,
T_HEVCSPS
*
ptSps
,
float
*
pfFramerate
)
{
{
if
(
ptVps
&&
ptVps
->
u8VpsTimingInfoPresentFlag
)
{
*
pfFramerate
=
(
float
)(
ptVps
->
u32VpsTimeScale
)
/
(
float
)(
ptVps
->
u32VpsNumUnitsInTick
);
}
else
if
(
ptSps
&&
ptSps
->
tVui
.
iVuiTimingInfoPresentFlag
&&
ptSps
->
iVuiPresent
)
{
*
pfFramerate
=
(
float
)(
ptSps
->
tVui
.
u32VuiTimeScale
)
/
(
float
)(
ptSps
->
tVui
.
u32VuiNumUnitsInTick
);
}
else
{
//vps sps可能不包含帧率
*
pfFramerate
=
0
.
0
F
;
RPT
(
RPT_WRN
,
"frame rate:0"
);
}
}
}
src/Extension/SPSParser.h
查看文件 @
dd80d6a6
...
@@ -237,184 +237,204 @@ typedef struct T_PPS {
...
@@ -237,184 +237,204 @@ typedef struct T_PPS {
typedef
struct
T_HEVCWindow
{
typedef
struct
T_HEVCWindow
{
unsigned
int
left_o
ffset
;
unsigned
int
uiLeftO
ffset
;
unsigned
int
right_o
ffset
;
unsigned
int
uiRightO
ffset
;
unsigned
int
top_o
ffset
;
unsigned
int
uiTopO
ffset
;
unsigned
int
bottom_o
ffset
;
unsigned
int
uiBottomO
ffset
;
}
T_HEVCWindow
;
}
T_HEVCWindow
;
typedef
struct
T_VUI
{
typedef
struct
T_VUI
{
T_AVRational
s
ar
;
T_AVRational
tS
ar
;
int
overscan_info_present_f
lag
;
int
iOverscanInfoPresentF
lag
;
int
overscan_appropriate_f
lag
;
int
iOverscanAppropriateF
lag
;
int
video_signal_type_present_f
lag
;
int
iVideoSignalTypePresentF
lag
;
int
video_f
ormat
;
int
iVideoF
ormat
;
int
video_full_range_f
lag
;
int
iVideoFullRangeF
lag
;
int
colour_description_present_f
lag
;
int
iColourDescriptionPresentF
lag
;
uint8_t
colour_p
rimaries
;
uint8_t
u8ColourP
rimaries
;
uint8_t
transfer_c
haracteristic
;
uint8_t
u8TransferC
haracteristic
;
uint8_t
matrix_c
oeffs
;
uint8_t
u8MatrixC
oeffs
;
int
chroma_loc_info_present_f
lag
;
int
iChromaLocInfoPresentF
lag
;
int
chroma_sample_loc_type_top_f
ield
;
int
iChromaSampleLocTypeTopF
ield
;
int
chroma_sample_loc_type_bottom_f
ield
;
int
iChromaSampleLocTypeBottomF
ield
;
int
neutra_chroma_indication_f
lag
;
int
iNeutraChromaIndicationF
lag
;
int
field_seq_f
lag
;
int
iFieldSeqF
lag
;
int
frame_field_info_present_f
lag
;
int
iFrameFieldInfoPresentF
lag
;
int
default_display_window_f
lag
;
int
iDefaultDisplayWindowF
lag
;
T_HEVCWindow
def_disp_w
in
;
T_HEVCWindow
tDefDispW
in
;
int
vui_timing_info_present_f
lag
;
int
iVuiTimingInfoPresentF
lag
;
uint32_t
vui_num_units_in_t
ick
;
uint32_t
u32VuiNumUnitsInT
ick
;
uint32_t
vui_time_s
cale
;
uint32_t
u32VuiTimeS
cale
;
int
vui_poc_proportional_to_timing_f
lag
;
int
iVuiPocProportionalToTimingF
lag
;
int
vui_num_ticks_poc_diff_one_m
inus1
;
int
iVuiNumTicksPocDiffOneM
inus1
;
int
vui_hrd_parameters_present_f
lag
;
int
iVuiHrdParametersPresentF
lag
;
int
bitstream_restriction_f
lag
;
int
iBitstreamRestrictionF
lag
;
int
tiles_fixed_structure_f
lag
;
int
iTilesFixedStructureF
lag
;
int
motion_vectors_over_pic_boundaries_f
lag
;
int
iMotionVectorsOverPicBoundariesF
lag
;
int
restricted_ref_pic_lists_f
lag
;
int
iRestrictedRefPicListsF
lag
;
int
min_spatial_segmentation_i
dc
;
int
iMinSpatialSegmentationI
dc
;
int
max_bytes_per_pic_d
enom
;
int
iMaxBytesPerPicD
enom
;
int
max_bits_per_min_cu_d
enom
;
int
iMaxBitsPerMinCuD
enom
;
int
log2_max_mv_length_h
orizontal
;
int
iLog2MaxMvLengthH
orizontal
;
int
log2_max_mv_length_v
ertical
;
int
iLog2MaxMvLengthV
ertical
;
}
T_VUI
;
}
T_VUI
;
typedef
struct
T_PTLCommon
{
typedef
struct
T_PTLCommon
{
uint8_t
profile_s
pace
;
uint8_t
u8ProfileS
pace
;
uint8_t
tier_f
lag
;
uint8_t
u8TierF
lag
;
uint8_t
profile_i
dc
;
uint8_t
u8ProfileI
dc
;
uint8_t
profile_compatibility_f
lag
[
32
];
uint8_t
au8ProfileCompatibilityF
lag
[
32
];
uint8_t
level_i
dc
;
uint8_t
u8LevelI
dc
;
uint8_t
progressive_source_f
lag
;
uint8_t
u8ProgressiveSourceF
lag
;
uint8_t
interlaced_source_f
lag
;
uint8_t
u8InterlacedSourceF
lag
;
uint8_t
non_packed_constraint_f
lag
;
uint8_t
u8NonPackedConstraintF
lag
;
uint8_t
frame_only_constraint_f
lag
;
uint8_t
u8FrameOnlyConstraintF
lag
;
}
T_PTLCommon
;
}
T_PTLCommon
;
typedef
struct
T_PTL
{
typedef
struct
T_PTL
{
T_PTLCommon
general_p
tl
;
T_PTLCommon
tGeneralP
tl
;
T_PTLCommon
sub_layer_p
tl
[
HEVC_MAX_SUB_LAYERS
];
T_PTLCommon
atSubLayerP
tl
[
HEVC_MAX_SUB_LAYERS
];
uint8_t
sub_layer_profile_present_f
lag
[
HEVC_MAX_SUB_LAYERS
];
uint8_t
au8SubLayerProfilePresentF
lag
[
HEVC_MAX_SUB_LAYERS
];
uint8_t
sub_layer_level_present_f
lag
[
HEVC_MAX_SUB_LAYERS
];
uint8_t
au8SubLayerLevelPresentF
lag
[
HEVC_MAX_SUB_LAYERS
];
}
T_PTL
;
}
T_PTL
;
typedef
struct
T_ScalingList
{
typedef
struct
T_ScalingList
{
/* This is a little wasteful, since sizeID 0 only needs 8 coeffs,
/* This is a little wasteful, since sizeID 0 only needs 8 coeffs,
* and size ID 3 only has 2 arrays, not 6. */
* and size ID 3 only has 2 arrays, not 6. */
uint8_t
s
l
[
4
][
6
][
64
];
uint8_t
aaau8S
l
[
4
][
6
][
64
];
uint8_t
sl_d
c
[
2
][
6
];
uint8_t
aau8SlD
c
[
2
][
6
];
}
T_ScalingList
;
}
T_ScalingList
;
typedef
struct
T_ShortTermRPS
{
typedef
struct
T_ShortTermRPS
{
unsigned
int
num_negative_p
ics
;
unsigned
int
uiNumNegativeP
ics
;
int
num_delta_p
ocs
;
int
iNumDeltaP
ocs
;
int
rps_idx_num_delta_p
ocs
;
int
iRpsIdxNumDeltaP
ocs
;
int32_t
delta_p
oc
[
32
];
int32_t
au32DeltaP
oc
[
32
];
uint8_t
u
sed
[
32
];
uint8_t
au8U
sed
[
32
];
}
T_ShortTermRPS
;
}
T_ShortTermRPS
;
typedef
struct
T_HEVCVPS
{
uint8_t
u8VpsTemporalIdNestingFlag
;
int
iVpsMaxLayers
;
int
iVpsMaxSubLayers
;
///< vps_max_temporal_layers_minus1 + 1
T_PTL
tPtl
;
int
iVpsSubLayerOrderingInfoPresentFlag
;
unsigned
int
uiVpsMaxDecPicBuffering
[
HEVC_MAX_SUB_LAYERS
];
unsigned
int
auiVpsNumReorderPics
[
HEVC_MAX_SUB_LAYERS
];
unsigned
int
auiVpsMaxLatencyIncrease
[
HEVC_MAX_SUB_LAYERS
];
int
iVpsMaxLayerId
;
int
iVpsNumLayerSets
;
///< vps_num_layer_sets_minus1 + 1
uint8_t
u8VpsTimingInfoPresentFlag
;
uint32_t
u32VpsNumUnitsInTick
;
uint32_t
u32VpsTimeScale
;
uint8_t
u8VpsPocProportionalToTimingFlag
;
int
iVpsNumTicksPocDiffOne
;
///< vps_num_ticks_poc_diff_one_minus1 + 1
int
iVpsNumHrdParameters
;
}
T_HEVCVPS
;
typedef
struct
T_HEVCSPS
{
typedef
struct
T_HEVCSPS
{
unsigned
vps_i
d
;
unsigned
int
uiVpsI
d
;
int
chroma_format_i
dc
;
int
iChromaFormatI
dc
;
uint8_t
separate_colour_plane_f
lag
;
uint8_t
u8SeparateColourPlaneF
lag
;
///< output (i.e. cropped) values
///< output (i.e. cropped) values
int
output_width
,
output_h
eight
;
int
iIutputWidth
,
iOutputH
eight
;
T_HEVCWindow
output_w
indow
;
T_HEVCWindow
tOutputW
indow
;
T_HEVCWindow
pic_conf_w
in
;
T_HEVCWindow
tPicConfW
in
;
int
bit_depth
;
int
iBitDepth
;
int
bit_depth_chroma
;
int
iBitDepthChroma
;
int
pixel_shift
;
int
iPixelShift
;
// enum AVPixelFormat pix_fmt;
unsigned
int
log2_max_poc_l
sb
;
unsigned
int
uiLog2MaxPocL
sb
;
int
pcm_enabled_f
lag
;
int
iPcmEnabledF
lag
;
int
max_sub_l
ayers
;
int
iMaxSubL
ayers
;
struct
{
struct
{
int
max_dec_pic_b
uffering
;
int
iMaxDecPicB
uffering
;
int
num_reorder_p
ics
;
int
iNumReorderP
ics
;
int
max_latency_i
ncrease
;
int
iMaxLatencyI
ncrease
;
}
temporal_l
ayer
[
HEVC_MAX_SUB_LAYERS
];
}
stTemporalL
ayer
[
HEVC_MAX_SUB_LAYERS
];
uint8_t
temporal_id_nesting_f
lag
;
uint8_t
u8temporalIdNestingF
lag
;
T_VUI
v
ui
;
T_VUI
tV
ui
;
T_PTL
p
tl
;
T_PTL
tP
tl
;
uint8_t
scaling_list_enable_f
lag
;
uint8_t
u8ScalingListEnableF
lag
;
T_ScalingList
scaling_l
ist
;
T_ScalingList
tScalingL
ist
;
unsigned
int
nb_st_r
ps
;
unsigned
int
uiNbStR
ps
;
T_ShortTermRPS
st_r
ps
[
HEVC_MAX_SHORT_TERM_RPS_COUNT
];
T_ShortTermRPS
atStR
ps
[
HEVC_MAX_SHORT_TERM_RPS_COUNT
];
uint8_t
amp_enabled_f
lag
;
uint8_t
u8AmpEnabledF
lag
;
uint8_t
sao_e
nabled
;
uint8_t
u8SaoE
nabled
;
uint8_t
long_term_ref_pics_present_f
lag
;
uint8_t
u8LongTermRefPicsPresentF
lag
;
uint16_t
lt_ref_pic_poc_lsb_s
ps
[
32
];
uint16_t
au16LtRefPicPocLsbS
ps
[
32
];
uint8_t
used_by_curr_pic_lt_sps_f
lag
[
32
];
uint8_t
au8UsedByCurrPicLtSpsF
lag
[
32
];
uint8_t
num_long_term_ref_pics_s
ps
;
uint8_t
u8NumLongTermRefPicsS
ps
;
struct
{
struct
{
uint8_t
bit_d
epth
;
uint8_t
u8BitD
epth
;
uint8_t
bit_depth_c
hroma
;
uint8_t
u8BitDepthC
hroma
;
unsigned
int
log2_min_pcm_cb_s
ize
;
unsigned
int
uiLog2MinPcmCbS
ize
;
unsigned
int
log2_max_pcm_cb_s
ize
;
unsigned
int
uiLog2MaxPcmCbS
ize
;
uint8_t
loop_filter_disable_f
lag
;
uint8_t
u8LoopFilterDisableF
lag
;
}
pcm
;
}
pcm
;
uint8_t
sps_temporal_mvp_enabled_flag
;
uint8_t
u8SpsTemporalMvpEnabledFlag
;
uint8_t
sps_strong_intra_smoothing_enable_flag
;
uint8_t
u8SpsStrongIntraMmoothingEnableFlag
;
unsigned
int
log2_min_cb_size
;
unsigned
int
uiLog2MinCbSize
;
unsigned
int
log2_diff_max_min_coding_block_size
;
unsigned
int
uiLog2DiffMaxMinCodingBlockSize
;
unsigned
int
log2_min_tb_size
;
unsigned
int
uiLog2MinTbSize
;
unsigned
int
log2_max_trafo_size
;
unsigned
int
uiLog2MaxTrafoSize
;
unsigned
int
log2_ctb_size
;
unsigned
int
uiLog2CtbSize
;
unsigned
int
log2_min_pu_size
;
unsigned
int
uiLog2MinPuSize
;
int
max_transform_hierarchy_depth_inter
;
int
iMaxTransformHierarchyDepthInter
;
int
max_transform_hierarchy_depth_intra
;
int
iMaxTransformHierarchyDepthIntra
;
int
transform_skip_rotation_enabled_flag
;
int
iTransformSkipRotationEnabledFlag
;
int
transform_skip_context_enabled_flag
;
int
iTransformSkipContextEnabledFlag
;
int
implicit_rdpcm_enabled_flag
;
int
iImplicitRdpcmEnabledFlag
;
int
explicit_rdpcm_enabled_flag
;
int
iExplicitRdpcmEnabledFlag
;
int
intra_smoothing_disabled_flag
;
int
iIntraSmoothingDisabledFlag
;
int
persistent_rice_adaptation_enabled_flag
;
int
iHighPrecisionOffsetsEnabledFlag
;
int
iPersistentRiceAdaptationEnabledFlag
;
///< coded frame dimension in various units
///< coded frame dimension in various units
int
width
;
int
iWidth
;
int
height
;
int
iHeight
;
int
ctb_width
;
int
iCtbWidth
;
int
ctb_height
;
int
iCtbHeight
;
int
ctb_size
;
int
iCtbSize
;
int
min_cb_width
;
int
iMinCbWidth
;
int
min_cb_height
;
int
iMinCbHeight
;
int
min_tb_width
;
int
iMinTbWidth
;
int
min_tb_height
;
int
iMinTbHeight
;
int
min_pu_width
;
int
iMinPuWidth
;
int
min_pu_height
;
int
iMinPuHeight
;
int
tb_mask
;
int
iTbMask
;
int
hshift
[
3
];
int
aiHshift
[
3
];
int
vshift
[
3
];
int
aiVshift
[
3
];
int
qp_bd_offset
;
int
iQpBdOffset
;
uint8_t
data
[
4096
];
int
iVuiPresent
;
int
data_size
;
}
T_HEVCSPS
;
}
T_HEVCSPS
;
...
@@ -428,13 +448,15 @@ typedef struct T_GetBitContext{
...
@@ -428,13 +448,15 @@ typedef struct T_GetBitContext{
int
h264DecSeqParameterSet
(
void
*
pvBuf
,
T_SPS
*
ptSps
);
int
h264DecSeqParameterSet
(
void
*
pvBuf
,
T_SPS
*
ptSps
);
int
h265DecSeqParameterSet
(
void
*
pvBufSrc
,
T_HEVCSPS
*
p_sps
);
int
h265DecSeqParameterSet
(
void
*
pvBufSrc
,
T_HEVCSPS
*
ptSps
);
int
h265DecVideoParameterSet
(
void
*
pvBufSrc
,
T_HEVCVPS
*
ptVps
);
void
h264GetWidthHeight
(
T_SPS
*
ptSps
,
int
*
piWidth
,
int
*
piHeight
);
void
h264GetWidthHeight
(
T_SPS
*
ptSps
,
int
*
piWidth
,
int
*
piHeight
);
void
h265GetWidthHeight
(
T_HEVCSPS
*
ptSps
,
int
*
piWidth
,
int
*
piHeight
);
void
h265GetWidthHeight
(
T_HEVCSPS
*
ptSps
,
int
*
piWidth
,
int
*
piHeight
);
void
h264GeFramerate
(
T_SPS
*
ptSps
,
float
*
pfFramerate
);
void
h264GeFramerate
(
T_SPS
*
ptSps
,
float
*
pfFramerate
);
void
h265GeFramerate
(
T_HEVC
SPS
*
ptSps
,
float
*
pfFramerate
);
void
h265GeFramerate
(
T_HEVC
VPS
*
ptVps
,
T_HEVCSPS
*
ptSps
,
float
*
pfFramerate
);
#if defined (__cplusplus)
#if defined (__cplusplus)
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论