Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Steve Lhomme
vlc
Commits
0da5762a
Commit
0da5762a
authored
Dec 17, 2015
by
François Cartegnie
🤞
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
packetizer: h264: update sps/pps parsing
parent
5f685c9f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
212 additions
and
154 deletions
+212
-154
modules/codec/Makefile.am
modules/codec/Makefile.am
+3
-3
modules/codec/omxil/mediacodec.c
modules/codec/omxil/mediacodec.c
+31
-9
modules/packetizer/h264.c
modules/packetizer/h264.c
+51
-36
modules/packetizer/h264_nal.c
modules/packetizer/h264_nal.c
+116
-94
modules/packetizer/h264_nal.h
modules/packetizer/h264_nal.h
+11
-12
No files found.
modules/codec/Makefile.am
View file @
0da5762a
...
...
@@ -419,9 +419,9 @@ libiomx_plugin_la_LIBADD = $(libomxil_plugin_la_LIBADD)
libmediacodec_plugin_la_CPPFLAGS
=
$(AM_CPPFLAGS)
-I
$(srcdir)
/codec/omxil
libmediacodec_plugin_la_SOURCES
=
codec/omxil/mediacodec.c codec/omxil/mediacodec.h
\
codec/omxil/mediacodec_jni.c codec/omxil/mediacodec_ndk.c codec/omxil/utils.c
\
video_chroma/copy.c
video_output/android/utils.c
video_output/android/utils.h
packetizer/h
264_nal.c
packetizer/h264_nal.h
video_chroma/copy.c
\
video_output/android/utils.c video_output/android/utils.h
\
packetizer/h
xxx_nal.h packetizer/h264_nal.c packetizer/h264_nal.h
\
packetizer/hevc_nal.c packetizer/hevc_nal.h
codec_LTLIBRARIES
+=
$(LTLIBomxil)
$(LTLIBomxil_vout)
...
...
modules/codec/omxil/mediacodec.c
View file @
0da5762a
...
...
@@ -44,6 +44,7 @@
#include "mediacodec.h"
#include "../../packetizer/h264_nal.h"
#include "../../packetizer/hevc_nal.h"
#include "../../packetizer/hxxx_nal.h"
#include <OMX_Core.h>
#include <OMX_Component.h>
#include "omxil_utils.h"
...
...
@@ -262,19 +263,31 @@ static int H264SetCSD(decoder_t *p_dec, void *p_buf, size_t i_size,
bool
*
p_size_changed
)
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
struct
h264_nal_sps
sps
;
uint8_t
*
p_sps_buf
=
NULL
,
*
p_pps_buf
=
NULL
;
size_t
i_sps_size
=
0
,
i_pps_size
=
0
;
/* Check if p_buf contains a valid SPS PPS */
if
(
h264_get_spspps
(
p_buf
,
i_size
,
&
p_sps_buf
,
&
i_sps_size
,
&
p_pps_buf
,
&
i_pps_size
)
==
0
&&
h264_parse_sps
(
p_sps_buf
,
i_sps_size
,
&
sps
)
==
0
&&
sps
.
i_width
&&
sps
.
i_height
)
&
p_pps_buf
,
&
i_pps_size
)
==
0
)
{
struct
csd
csd
[
2
];
int
i_csd_count
=
0
;
const
uint8_t
*
p_buffer
=
p_sps_buf
;
size_t
i_buffer
=
i_sps_size
;
if
(
!
hxxx_strip_AnnexB_startcode
(
&
p_buffer
,
&
i_buffer
))
return
VLC_EGENERIC
;
h264_sequence_parameter_set_t
*
p_sps
=
h264_decode_sps
(
p_buffer
,
i_buffer
,
true
);
if
(
!
p_sps
)
return
VLC_EGENERIC
;
if
(
!
p_sps
->
i_width
||
!
p_sps
->
i_height
)
{
h264_release_sps
(
p_sps
);
return
VLC_EGENERIC
;
}
if
(
i_sps_size
)
{
csd
[
i_csd_count
].
p_buf
=
p_sps_buf
;
...
...
@@ -292,23 +305,32 @@ static int H264SetCSD(decoder_t *p_dec, void *p_buf, size_t i_size,
if
(
!
CSDCmp
(
p_dec
,
csd
,
i_csd_count
))
{
msg_Warn
(
p_dec
,
"New SPS/PPS found, id: %d size: %dx%d sps: %d pps: %d"
,
sps
.
i_id
,
sps
.
i_width
,
sps
.
i_height
,
p_sps
->
i_id
,
p_sps
->
i_width
,
p_sps
->
i_height
,
i_sps_size
,
i_pps_size
);
/* In most use cases, p_sys->p_csd[0] contains a SPS, and
* p_sys->p_csd[1] contains a PPS */
if
(
CSDDup
(
p_dec
,
csd
,
i_csd_count
))
{
h264_release_sps
(
p_sps
);
return
VLC_ENOMEM
;
}
if
(
p_size_changed
)
*
p_size_changed
=
(
sps
.
i_width
!=
p_sys
->
u
.
video
.
i_width
||
sps
.
i_height
!=
p_sys
->
u
.
video
.
i_height
);
*
p_size_changed
=
(
p_sps
->
i_width
!=
p_sys
->
u
.
video
.
i_width
||
p_sps
->
i_height
!=
p_sys
->
u
.
video
.
i_height
);
p_sys
->
u
.
video
.
i_width
=
p_sps
->
i_width
;
p_sys
->
u
.
video
.
i_height
=
p_sps
->
i_height
;
h264_release_sps
(
p_sps
);
p_sys
->
u
.
video
.
i_width
=
sps
.
i_width
;
p_sys
->
u
.
video
.
i_height
=
sps
.
i_height
;
return
VLC_SUCCESS
;
}
h264_release_sps
(
p_sps
);
}
return
VLC_EGENERIC
;
}
...
...
modules/packetizer/h264.c
View file @
0da5762a
...
...
@@ -704,74 +704,89 @@ static block_t *OutputPicture( decoder_t *p_dec )
static
void
PutSPS
(
decoder_t
*
p_dec
,
block_t
*
p_frag
)
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
struct
h264_nal_sps
sps
;
if
(
h264_parse_sps
(
p_frag
->
p_buffer
,
p_frag
->
i_buffer
,
&
sps
)
!=
0
)
const
uint8_t
*
p_buffer
=
p_frag
->
p_buffer
;
size_t
i_buffer
=
p_frag
->
i_buffer
;
if
(
!
hxxx_strip_AnnexB_startcode
(
&
p_buffer
,
&
i_buffer
)
)
return
;
h264_sequence_parameter_set_t
*
p_sps
=
h264_decode_sps
(
p_buffer
,
i_buffer
,
true
);
if
(
!
p_sps
)
{
msg_Warn
(
p_dec
,
"invalid SPS (sps_id=%d)"
,
sps
.
i_id
);
msg_Warn
(
p_dec
,
"invalid SPS (sps_id=%d)"
,
p_sps
->
i_id
);
block_Release
(
p_frag
);
return
;
}
p_dec
->
fmt_out
.
i_profile
=
sps
.
i_profile
;
p_dec
->
fmt_out
.
i_level
=
sps
.
i_level
;
p_dec
->
fmt_out
.
video
.
i_width
=
sps
.
i_width
;
p_dec
->
fmt_out
.
video
.
i_height
=
sps
.
i_height
;
if
(
sps
.
vui
.
i_sar_num
!=
0
&&
sps
.
vui
.
i_sar_den
!=
0
)
p_dec
->
fmt_out
.
i_profile
=
p_sps
->
i_profile
;
p_dec
->
fmt_out
.
i_level
=
p_sps
->
i_level
;
p_dec
->
fmt_out
.
video
.
i_width
=
p_sps
->
i_width
;
p_dec
->
fmt_out
.
video
.
i_height
=
p_sps
->
i_height
;
if
(
p_sps
->
vui
.
i_sar_num
!=
0
&&
p_sps
->
vui
.
i_sar_den
!=
0
)
{
p_dec
->
fmt_out
.
video
.
i_sar_num
=
sps
.
vui
.
i_sar_num
;
p_dec
->
fmt_out
.
video
.
i_sar_den
=
sps
.
vui
.
i_sar_den
;
p_dec
->
fmt_out
.
video
.
i_sar_num
=
p_sps
->
vui
.
i_sar_num
;
p_dec
->
fmt_out
.
video
.
i_sar_den
=
p_sps
->
vui
.
i_sar_den
;
}
p_sys
->
i_log2_max_frame_num
=
sps
.
i_log2_max_frame_num
;
p_sys
->
b_frame_mbs_only
=
sps
.
b_frame_mbs_only
;
p_sys
->
i_pic_order_cnt_type
=
sps
.
i_pic_order_cnt_type
;
p_sys
->
i_delta_pic_order_always_zero_flag
=
sps
.
i_delta_pic_order_always_zero_flag
;
p_sys
->
i_log2_max_pic_order_cnt_lsb
=
sps
.
i_log2_max_pic_order_cnt_lsb
;
p_sys
->
i_log2_max_frame_num
=
p_sps
->
i_log2_max_frame_num
;
p_sys
->
b_frame_mbs_only
=
p_sps
->
b_frame_mbs_only
;
p_sys
->
i_pic_order_cnt_type
=
p_sps
->
i_pic_order_cnt_type
;
p_sys
->
i_delta_pic_order_always_zero_flag
=
p_sps
->
i_delta_pic_order_always_zero_flag
;
p_sys
->
i_log2_max_pic_order_cnt_lsb
=
p_sps
->
i_log2_max_pic_order_cnt_lsb
;
if
(
sps
.
vui
.
b_valid
)
if
(
p_sps
->
vui
.
b_valid
)
{
p_sys
->
b_timing_info_present_flag
=
sps
.
vui
.
b_timing_info_present_flag
;
p_sys
->
i_num_units_in_tick
=
sps
.
vui
.
i_num_units_in_tick
;
p_sys
->
i_time_scale
=
sps
.
vui
.
i_time_scale
;
p_sys
->
b_fixed_frame_rate
=
sps
.
vui
.
b_fixed_frame_rate
;
p_sys
->
b_pic_struct_present_flag
=
sps
.
vui
.
b_pic_struct_present_flag
;
p_sys
->
b_cpb_dpb_delays_present_flag
=
sps
.
vui
.
b_cpb_dpb_delays_present_flag
;
p_sys
->
i_cpb_removal_delay_length_minus1
=
sps
.
vui
.
i_cpb_removal_delay_length_minus1
;
p_sys
->
i_dpb_output_delay_length_minus1
=
sps
.
vui
.
i_dpb_output_delay_length_minus1
;
p_sys
->
b_timing_info_present_flag
=
p_sps
->
vui
.
b_timing_info_present_flag
;
p_sys
->
i_num_units_in_tick
=
p_sps
->
vui
.
i_num_units_in_tick
;
p_sys
->
i_time_scale
=
p_sps
->
vui
.
i_time_scale
;
p_sys
->
b_fixed_frame_rate
=
p_sps
->
vui
.
b_fixed_frame_rate
;
p_sys
->
b_pic_struct_present_flag
=
p_sps
->
vui
.
b_pic_struct_present_flag
;
p_sys
->
b_cpb_dpb_delays_present_flag
=
p_sps
->
vui
.
b_cpb_dpb_delays_present_flag
;
p_sys
->
i_cpb_removal_delay_length_minus1
=
p_sps
->
vui
.
i_cpb_removal_delay_length_minus1
;
p_sys
->
i_dpb_output_delay_length_minus1
=
p_sps
->
vui
.
i_dpb_output_delay_length_minus1
;
}
/* We have a new SPS */
if
(
!
p_sys
->
b_sps
)
msg_Dbg
(
p_dec
,
"found NAL_SPS (sps_id=%d)"
,
sps
.
i_id
);
msg_Dbg
(
p_dec
,
"found NAL_SPS (sps_id=%d)"
,
p_sps
->
i_id
);
p_sys
->
b_sps
=
true
;
if
(
p_sys
->
pp_sps
[
sps
.
i_id
]
)
block_Release
(
p_sys
->
pp_sps
[
sps
.
i_id
]
);
p_sys
->
pp_sps
[
sps
.
i_id
]
=
p_frag
;
if
(
p_sys
->
pp_sps
[
p_sps
->
i_id
]
)
block_Release
(
p_sys
->
pp_sps
[
p_sps
->
i_id
]
);
p_sys
->
pp_sps
[
p_sps
->
i_id
]
=
p_frag
;
h264_release_sps
(
p_sps
);
}
static
void
PutPPS
(
decoder_t
*
p_dec
,
block_t
*
p_frag
)
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
struct
h264_nal_pps
pps
;
const
uint8_t
*
p_buffer
=
p_frag
->
p_buffer
;
size_t
i_buffer
=
p_frag
->
i_buffer
;
if
(
h264_parse_pps
(
p_frag
->
p_buffer
,
p_frag
->
i_buffer
,
&
pps
)
!=
0
)
if
(
!
hxxx_strip_AnnexB_startcode
(
&
p_buffer
,
&
i_buffer
)
)
return
;
h264_picture_parameter_set_t
*
p_pps
=
h264_decode_pps
(
p_buffer
,
i_buffer
,
true
);
if
(
!
p_pps
)
{
msg_Warn
(
p_dec
,
"invalid PPS (pps_id=%d sps_id=%d)"
,
p
ps
.
i_id
,
pps
.
i_sps_id
);
msg_Warn
(
p_dec
,
"invalid PPS (pps_id=%d sps_id=%d)"
,
p
_pps
->
i_id
,
p_pps
->
i_sps_id
);
block_Release
(
p_frag
);
return
;
}
p_sys
->
i_pic_order_present_flag
=
p
ps
.
i_pic_order_present_flag
;
p_sys
->
i_pic_order_present_flag
=
p
_pps
->
i_pic_order_present_flag
;
/* We have a new PPS */
if
(
!
p_sys
->
b_pps
)
msg_Dbg
(
p_dec
,
"found NAL_PPS (pps_id=%d sps_id=%d)"
,
p
ps
.
i_id
,
pps
.
i_sps_id
);
msg_Dbg
(
p_dec
,
"found NAL_PPS (pps_id=%d sps_id=%d)"
,
p
_pps
->
i_id
,
p_pps
->
i_sps_id
);
p_sys
->
b_pps
=
true
;
if
(
p_sys
->
pp_pps
[
pps
.
i_id
]
)
block_Release
(
p_sys
->
pp_pps
[
pps
.
i_id
]
);
p_sys
->
pp_pps
[
pps
.
i_id
]
=
p_frag
;
if
(
p_sys
->
pp_pps
[
p_pps
->
i_id
]
)
block_Release
(
p_sys
->
pp_pps
[
p_pps
->
i_id
]
);
p_sys
->
pp_pps
[
p_pps
->
i_id
]
=
p_frag
;
h264_release_pps
(
p_pps
);
}
static
bool
ParseSlice
(
decoder_t
*
p_dec
,
bool
*
pb_new_picture
,
slice_t
*
p_slice
,
...
...
modules/packetizer/h264_nal.c
View file @
0da5762a
...
...
@@ -399,30 +399,24 @@ int h264_get_spspps( uint8_t *p_buf, size_t i_buf,
return
0
;
}
int
h264_parse_sps
(
const
uint8_t
*
p_sps_buf
,
int
i_sps_size
,
struct
h264_nal_sps
*
p_sps
)
void
h264_release_sps
(
h264_sequence_parameter_set_t
*
p_sps
)
{
bs_t
s
;
int
i_tmp
;
if
(
i_sps_size
<
5
||
(
p_sps_buf
[
4
]
&
0x1f
)
!=
H264_NAL_SPS
)
return
-
1
;
memset
(
p_sps
,
0
,
sizeof
(
struct
h264_nal_sps
)
);
free
(
p_sps
);
}
bs_init
(
&
s
,
&
p_sps_buf
[
5
],
i_sps_size
-
5
);
unsigned
i_bitflow
=
0
;
s
.
p_fwpriv
=
&
i_bitflow
;
s
.
pf_forward
=
hxxx_bsfw_ep3b_to_rbsp
;
/* Does the emulated 3bytes conversion to rbsp */
static
bool
h264_parse_sequence_parameter_set_rbsp
(
bs_t
*
p_bs
,
h264_sequence_parameter_set_t
*
p_sps
)
{
int
i_tmp
;
int
i_profile_idc
=
bs_read
(
&
s
,
8
);
int
i_profile_idc
=
bs_read
(
p_b
s
,
8
);
p_sps
->
i_profile
=
i_profile_idc
;
p_sps
->
i_profile_compatibility
=
bs_read
(
&
s
,
8
);
p_sps
->
i_level
=
bs_read
(
&
s
,
8
);
p_sps
->
i_profile_compatibility
=
bs_read
(
p_b
s
,
8
);
p_sps
->
i_level
=
bs_read
(
p_b
s
,
8
);
/* sps id */
p_sps
->
i_id
=
bs_read_ue
(
&
s
);
p_sps
->
i_id
=
bs_read_ue
(
p_b
s
);
if
(
p_sps
->
i_id
>=
H264_SPS_MAX
)
return
-
1
;
return
false
;
if
(
i_profile_idc
==
PROFILE_H264_HIGH
||
i_profile_idc
==
PROFILE_H264_HIGH_10
||
...
...
@@ -439,23 +433,23 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
i_profile_idc
==
PROFILE_H264_MFC_HIGH
)
{
/* chroma_format_idc */
const
int
i_chroma_format_idc
=
bs_read_ue
(
&
s
);
const
int
i_chroma_format_idc
=
bs_read_ue
(
p_b
s
);
if
(
i_chroma_format_idc
==
3
)
bs_skip
(
&
s
,
1
);
/* separate_colour_plane_flag */
bs_skip
(
p_b
s
,
1
);
/* separate_colour_plane_flag */
/* bit_depth_luma_minus8 */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* bit_depth_chroma_minus8 */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* qpprime_y_zero_transform_bypass_flag */
bs_skip
(
&
s
,
1
);
bs_skip
(
p_b
s
,
1
);
/* seq_scaling_matrix_present_flag */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
{
for
(
int
i
=
0
;
i
<
((
3
!=
i_chroma_format_idc
)
?
8
:
12
);
i
++
)
{
/* seq_scaling_list_present_flag[i] */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
!
i_tmp
)
continue
;
const
int
i_size_of_scaling_list
=
(
i
<
6
)
?
16
:
64
;
...
...
@@ -467,7 +461,7 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
if
(
i_nextscale
!=
0
)
{
/* delta_scale */
i_tmp
=
bs_read_se
(
&
s
);
i_tmp
=
bs_read_se
(
p_b
s
);
i_nextscale
=
(
i_lastscale
+
i_tmp
+
256
)
%
256
;
/* useDefaultScalingMatrixFlag = ... */
}
...
...
@@ -479,15 +473,15 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
}
/* Skip i_log2_max_frame_num */
p_sps
->
i_log2_max_frame_num
=
bs_read_ue
(
&
s
);
p_sps
->
i_log2_max_frame_num
=
bs_read_ue
(
p_b
s
);
if
(
p_sps
->
i_log2_max_frame_num
>
12
)
p_sps
->
i_log2_max_frame_num
=
12
;
/* Read poc_type */
p_sps
->
i_pic_order_cnt_type
=
bs_read_ue
(
&
s
);
p_sps
->
i_pic_order_cnt_type
=
bs_read_ue
(
p_b
s
);
if
(
p_sps
->
i_pic_order_cnt_type
==
0
)
{
/* skip i_log2_max_poc_lsb */
p_sps
->
i_log2_max_pic_order_cnt_lsb
=
bs_read_ue
(
&
s
);
p_sps
->
i_log2_max_pic_order_cnt_lsb
=
bs_read_ue
(
p_b
s
);
if
(
p_sps
->
i_log2_max_pic_order_cnt_lsb
>
12
)
p_sps
->
i_log2_max_pic_order_cnt_lsb
=
12
;
}
...
...
@@ -495,61 +489,61 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
{
int
i_cycle
;
/* skip b_delta_pic_order_always_zero */
p_sps
->
i_delta_pic_order_always_zero_flag
=
bs_read
(
&
s
,
1
);
p_sps
->
i_delta_pic_order_always_zero_flag
=
bs_read
(
p_b
s
,
1
);
/* skip i_offset_for_non_ref_pic */
bs_read_se
(
&
s
);
bs_read_se
(
p_b
s
);
/* skip i_offset_for_top_to_bottom_field */
bs_read_se
(
&
s
);
bs_read_se
(
p_b
s
);
/* read i_num_ref_frames_in_poc_cycle */
i_cycle
=
bs_read_ue
(
&
s
);
i_cycle
=
bs_read_ue
(
p_b
s
);
if
(
i_cycle
>
256
)
i_cycle
=
256
;
while
(
i_cycle
>
0
)
{
/* skip i_offset_for_ref_frame */
bs_read_se
(
&
s
);
bs_read_se
(
p_b
s
);
i_cycle
--
;
}
}
/* i_num_ref_frames */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* b_gaps_in_frame_num_value_allowed */
bs_skip
(
&
s
,
1
);
bs_skip
(
p_b
s
,
1
);
/* Read size */
p_sps
->
i_width
=
16
*
(
bs_read_ue
(
&
s
)
+
1
);
p_sps
->
i_height
=
16
*
(
bs_read_ue
(
&
s
)
+
1
);
p_sps
->
i_width
=
16
*
(
bs_read_ue
(
p_b
s
)
+
1
);
p_sps
->
i_height
=
16
*
(
bs_read_ue
(
p_b
s
)
+
1
);
/* b_frame_mbs_only */
p_sps
->
b_frame_mbs_only
=
bs_read
(
&
s
,
1
);
p_sps
->
b_frame_mbs_only
=
bs_read
(
p_b
s
,
1
);
p_sps
->
i_height
*=
(
2
-
p_sps
->
b_frame_mbs_only
);
if
(
p_sps
->
b_frame_mbs_only
==
0
)
{
bs_skip
(
&
s
,
1
);
bs_skip
(
p_b
s
,
1
);
}
/* b_direct8x8_inference */
bs_skip
(
&
s
,
1
);
bs_skip
(
p_b
s
,
1
);
/* crop */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
{
/* left */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* right */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* top */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* bottom */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
}
/* vui */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
{
p_sps
->
vui
.
b_valid
=
true
;
/* read the aspect ratio part if any */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
{
static
const
struct
{
int
w
,
h
;
}
sar
[
17
]
=
...
...
@@ -560,7 +554,7 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
{
64
,
33
},
{
160
,
99
},
{
4
,
3
},
{
3
,
2
},
{
2
,
1
},
};
int
i_sar
=
bs_read
(
&
s
,
8
);
int
i_sar
=
bs_read
(
p_b
s
,
8
);
int
w
,
h
;
if
(
i_sar
<
17
)
...
...
@@ -570,8 +564,8 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
}
else
if
(
i_sar
==
255
)
{
w
=
bs_read
(
&
s
,
16
);
h
=
bs_read
(
&
s
,
16
);
w
=
bs_read
(
p_b
s
,
16
);
h
=
bs_read
(
p_b
s
,
16
);
}
else
{
...
...
@@ -592,97 +586,125 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
}
/* overscan */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
bs_read
(
&
s
,
1
);
bs_read
(
p_b
s
,
1
);
/* video signal type */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
{
bs_read
(
&
s
,
4
);
bs_read
(
p_b
s
,
4
);
/* colour desc */
bs_read
(
&
s
,
1
);
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
bs_read
(
&
s
,
24
);
bs_read
(
p_b
s
,
24
);
}
/* chroma loc info */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
{
bs_read_ue
(
&
s
);
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
bs_read_ue
(
p_b
s
);
}
/* timing info */
p_sps
->
vui
.
b_timing_info_present_flag
=
bs_read
(
&
s
,
1
);
p_sps
->
vui
.
b_timing_info_present_flag
=
bs_read
(
p_b
s
,
1
);
if
(
p_sps
->
vui
.
b_timing_info_present_flag
)
{
p_sps
->
vui
.
i_num_units_in_tick
=
bs_read
(
&
s
,
32
);
p_sps
->
vui
.
i_time_scale
=
bs_read
(
&
s
,
32
);
p_sps
->
vui
.
b_fixed_frame_rate
=
bs_read
(
&
s
,
1
);
p_sps
->
vui
.
i_num_units_in_tick
=
bs_read
(
p_b
s
,
32
);
p_sps
->
vui
.
i_time_scale
=
bs_read
(
p_b
s
,
32
);
p_sps
->
vui
.
b_fixed_frame_rate
=
bs_read
(
p_b
s
,
1
);
}
/* Nal hrd & VC1 hrd parameters */
p_sps
->
vui
.
b_cpb_dpb_delays_present_flag
=
false
;
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
{
p_sps
->
vui
.
b_cpb_dpb_delays_present_flag
=
true
;
uint32_t
count
=
bs_read_ue
(
&
s
)
+
1
;
bs_read
(
&
s
,
4
);
bs_read
(
&
s
,
4
);
uint32_t
count
=
bs_read_ue
(
p_b
s
)
+
1
;
bs_read
(
p_b
s
,
4
);
bs_read
(
p_b
s
,
4
);
for
(
uint32_t
i
=
0
;
i
<
count
;
i
++
)
{
bs_read_ue
(
&
s
);
bs_read_ue
(
&
s
);
bs_read
(
&
s
,
1
);
bs_read_ue
(
p_b
s
);
bs_read_ue
(
p_b
s
);
bs_read
(
p_b
s
,
1
);
}
bs_read
(
&
s
,
5
);
p_sps
->
vui
.
i_cpb_removal_delay_length_minus1
=
bs_read
(
&
s
,
5
);
p_sps
->
vui
.
i_dpb_output_delay_length_minus1
=
bs_read
(
&
s
,
5
);
bs_read
(
&
s
,
5
);
bs_read
(
p_b
s
,
5
);
p_sps
->
vui
.
i_cpb_removal_delay_length_minus1
=
bs_read
(
p_b
s
,
5
);
p_sps
->
vui
.
i_dpb_output_delay_length_minus1
=
bs_read
(
p_b
s
,
5
);
bs_read
(
p_b
s
,
5
);
}
}
if
(
p_sps
->
vui
.
b_cpb_dpb_delays_present_flag
)
bs_read
(
&
s
,
1
);
bs_read
(
p_b
s
,
1
);
/* pic struct info */
p_sps
->
vui
.
b_pic_struct_present_flag
=
bs_read
(
&
s
,
1
);
p_sps
->
vui
.
b_pic_struct_present_flag
=
bs_read
(
p_b
s
,
1
);
/* + unparsed remains */
}
return
0
;
return
true
;
}
int
h264_parse_pps
(
const
uint8_t
*
p_pps_buf
,
int
i_pps_size
,
struct
h264_nal_pps
*
p_pps
)
void
h264_release_pps
(
h264_picture_parameter_set_t
*
p_pps
)
{
bs_t
s
;
if
(
i_pps_size
<
5
||
(
p_pps_buf
[
4
]
&
0x1f
)
!=
H264_NAL_PPS
)
return
-
1
;
free
(
p_pps
);
}
memset
(
p_pps
,
0
,
sizeof
(
struct
h264_nal_pps
)
);
bs_init
(
&
s
,
&
p_pps_buf
[
5
],
i_pps_size
-
5
);
p_pps
->
i_id
=
bs_read_ue
(
&
s
);
// pps id
p_pps
->
i_sps_id
=
bs_read_ue
(
&
s
);
// sps id
static
bool
h264_parse_picture_parameter_set_rbsp
(
bs_t
*
p_bs
,
h264_picture_parameter_set_t
*
p_pps
)
{
p_pps
->
i_id
=
bs_read_ue
(
p_bs
);
// pps id
p_pps
->
i_sps_id
=
bs_read_ue
(
p_bs
);
// sps id
if
(
p_pps
->
i_id
>=
H264_PPS_MAX
||
p_pps
->
i_sps_id
>=
H264_SPS_MAX
)
{
return
-
1
;
}
bs_skip
(
&
s
,
1
);
// entropy coding mode flag
p_pps
->
i_pic_order_present_flag
=
bs_read
(
&
s
,
1
);
return
false
;
bs_skip
(
p_bs
,
1
);
// entropy coding mode flag
p_pps
->
i_pic_order_present_flag
=
bs_read
(
p_bs
,
1
);
/* TODO */
return
0
;
return
true
;
}
#define IMPL_h264_generic_decode( name, h264type, decode, release ) \
h264type * name( const uint8_t *p_buf, size_t i_buf, bool b_escaped ) \
{ \
h264type *p_h264type = calloc(1, sizeof(h264type)); \
if(likely(p_h264type)) \
{ \
bs_t bs; \
bs_init( &bs, p_buf, i_buf ); \
unsigned i_bitflow = 0; \
if( b_escaped ) \
{ \
bs.p_fwpriv = &i_bitflow; \
bs.pf_forward = hxxx_bsfw_ep3b_to_rbsp;
/* Does the emulated 3bytes conversion to rbsp */
\
} \
else (void) i_bitflow;\
bs_skip( &bs, 8 );
/* Skip nal_unit_header */
\
if( !decode( &bs, p_h264type ) ) \
{ \
release( p_h264type ); \
p_h264type = NULL; \
} \
} \
return p_h264type; \
}
IMPL_h264_generic_decode
(
h264_decode_sps
,
h264_sequence_parameter_set_t
,
h264_parse_sequence_parameter_set_rbsp
,
h264_release_sps
)
IMPL_h264_generic_decode
(
h264_decode_pps
,
h264_picture_parameter_set_t
,
h264_parse_picture_parameter_set_rbsp
,
h264_release_pps
)
block_t
*
h264_AnnexB_NAL_to_avcC
(
uint8_t
i_nal_length_size
,
const
uint8_t
*
p_sps_buf
,
size_t
i_sps_size
,
...
...
modules/packetizer/h264_nal.h
View file @
0da5762a
...
...
@@ -72,7 +72,16 @@ enum h264_sei_type_e
H264_SEI_RECOVERY_POINT
=
6
};
struct
h264_nal_sps
typedef
struct
h264_sequence_parameter_set_t
h264_sequence_parameter_set_t
;
typedef
struct
h264_picture_parameter_set_t
h264_picture_parameter_set_t
;
h264_sequence_parameter_set_t
*
h264_decode_sps
(
const
uint8_t
*
,
size_t
,
bool
);
h264_picture_parameter_set_t
*
h264_decode_pps
(
const
uint8_t
*
,
size_t
,
bool
);
void
h264_release_sps
(
h264_sequence_parameter_set_t
*
);
void
h264_release_pps
(
h264_picture_parameter_set_t
*
);
struct
h264_sequence_parameter_set_t
{
int
i_id
;
int
i_profile
,
i_profile_compatibility
,
i_level
;
...
...
@@ -97,7 +106,7 @@ struct h264_nal_sps
}
vui
;
};
struct
h264_
nal_pps
struct
h264_
picture_parameter_set_t
{
int
i_id
;
int
i_sps_id
;
...
...
@@ -130,16 +139,6 @@ int h264_get_spspps( uint8_t *p_buf, size_t i_buf,
uint8_t
**
pp_sps
,
size_t
*
p_sps_size
,
uint8_t
**
pp_pps
,
size_t
*
p_pps_size
);
/* Parse a SPS into the struct nal_sps
* Returns 0 in case of success */
int
h264_parse_sps
(
const
uint8_t
*
p_sps_buf
,
int
i_sps_size
,
struct
h264_nal_sps
*
p_sps
);
/* Parse a PPS into the struct nal_pps
* Returns 0 in case of success */
int
h264_parse_pps
(
const
uint8_t
*
p_pps_buf
,
int
i_pps_size
,
struct
h264_nal_pps
*
p_pps
);
/* Create a AVCDecoderConfigurationRecord from SPS/PPS
* Returns a valid block_t on success, must be freed with block_Release */
block_t
*
h264_AnnexB_NAL_to_avcC
(
uint8_t
i_nal_length_size
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment