Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
0da5762a
Commit
0da5762a
authored
Dec 17, 2015
by
Francois Cartegnie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
packetizer: h264: update sps/pps parsing
parent
5f685c9f
Changes
5
Show 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)
...
@@ -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_CPPFLAGS
=
$(AM_CPPFLAGS)
-I
$(srcdir)
/codec/omxil
libmediacodec_plugin_la_SOURCES
=
codec/omxil/mediacodec.c codec/omxil/mediacodec.h
\
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
\
codec/omxil/mediacodec_jni.c codec/omxil/mediacodec_ndk.c codec/omxil/utils.c
\
video_chroma/copy.c
video_chroma/copy.c
\
video_output/android/utils.c
video_output/android/utils.h
video_output/android/utils.c video_output/android/utils.h
\
packetizer/h
264_nal.c
packetizer/h264_nal.h
packetizer/h
xxx_nal.h packetizer/h264_nal.c packetizer/h264_nal.h
\
packetizer/hevc_nal.c packetizer/hevc_nal.h
packetizer/hevc_nal.c packetizer/hevc_nal.h
codec_LTLIBRARIES
+=
$(LTLIBomxil)
$(LTLIBomxil_vout)
codec_LTLIBRARIES
+=
$(LTLIBomxil)
$(LTLIBomxil_vout)
...
...
modules/codec/omxil/mediacodec.c
View file @
0da5762a
...
@@ -44,6 +44,7 @@
...
@@ -44,6 +44,7 @@
#include "mediacodec.h"
#include "mediacodec.h"
#include "../../packetizer/h264_nal.h"
#include "../../packetizer/h264_nal.h"
#include "../../packetizer/hevc_nal.h"
#include "../../packetizer/hevc_nal.h"
#include "../../packetizer/hxxx_nal.h"
#include <OMX_Core.h>
#include <OMX_Core.h>
#include <OMX_Component.h>
#include <OMX_Component.h>
#include "omxil_utils.h"
#include "omxil_utils.h"
...
@@ -262,19 +263,31 @@ static int H264SetCSD(decoder_t *p_dec, void *p_buf, size_t i_size,
...
@@ -262,19 +263,31 @@ static int H264SetCSD(decoder_t *p_dec, void *p_buf, size_t i_size,
bool
*
p_size_changed
)
bool
*
p_size_changed
)
{
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
struct
h264_nal_sps
sps
;
uint8_t
*
p_sps_buf
=
NULL
,
*
p_pps_buf
=
NULL
;
uint8_t
*
p_sps_buf
=
NULL
,
*
p_pps_buf
=
NULL
;
size_t
i_sps_size
=
0
,
i_pps_size
=
0
;
size_t
i_sps_size
=
0
,
i_pps_size
=
0
;
/* Check if p_buf contains a valid SPS PPS */
/* Check if p_buf contains a valid SPS PPS */
if
(
h264_get_spspps
(
p_buf
,
i_size
,
&
p_sps_buf
,
&
i_sps_size
,
if
(
h264_get_spspps
(
p_buf
,
i_size
,
&
p_sps_buf
,
&
i_sps_size
,
&
p_pps_buf
,
&
i_pps_size
)
==
0
&
p_pps_buf
,
&
i_pps_size
)
==
0
)
&&
h264_parse_sps
(
p_sps_buf
,
i_sps_size
,
&
sps
)
==
0
&&
sps
.
i_width
&&
sps
.
i_height
)
{
{
struct
csd
csd
[
2
];
struct
csd
csd
[
2
];
int
i_csd_count
=
0
;
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
)
if
(
i_sps_size
)
{
{
csd
[
i_csd_count
].
p_buf
=
p_sps_buf
;
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,
...
@@ -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
))
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"
,
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
);
i_sps_size
,
i_pps_size
);
/* In most use cases, p_sys->p_csd[0] contains a SPS, and
/* In most use cases, p_sys->p_csd[0] contains a SPS, and
* p_sys->p_csd[1] contains a PPS */
* p_sys->p_csd[1] contains a PPS */
if
(
CSDDup
(
p_dec
,
csd
,
i_csd_count
))
if
(
CSDDup
(
p_dec
,
csd
,
i_csd_count
))
{
h264_release_sps
(
p_sps
);
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
}
if
(
p_size_changed
)
if
(
p_size_changed
)
*
p_size_changed
=
(
sps
.
i_width
!=
p_sys
->
u
.
video
.
i_width
*
p_size_changed
=
(
p_sps
->
i_width
!=
p_sys
->
u
.
video
.
i_width
||
sps
.
i_height
!=
p_sys
->
u
.
video
.
i_height
);
||
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
;
return
VLC_SUCCESS
;
}
}
h264_release_sps
(
p_sps
);
}
}
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
...
...
modules/packetizer/h264.c
View file @
0da5762a
...
@@ -704,74 +704,89 @@ static block_t *OutputPicture( decoder_t *p_dec )
...
@@ -704,74 +704,89 @@ static block_t *OutputPicture( decoder_t *p_dec )
static
void
PutSPS
(
decoder_t
*
p_dec
,
block_t
*
p_frag
)
static
void
PutSPS
(
decoder_t
*
p_dec
,
block_t
*
p_frag
)
{
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
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
);
block_Release
(
p_frag
);
return
;
return
;
}
}
p_dec
->
fmt_out
.
i_profile
=
sps
.
i_profile
;
p_dec
->
fmt_out
.
i_profile
=
p_sps
->
i_profile
;
p_dec
->
fmt_out
.
i_level
=
sps
.
i_level
;
p_dec
->
fmt_out
.
i_level
=
p_sps
->
i_level
;
p_dec
->
fmt_out
.
video
.
i_width
=
sps
.
i_width
;
p_dec
->
fmt_out
.
video
.
i_width
=
p_sps
->
i_width
;
p_dec
->
fmt_out
.
video
.
i_height
=
sps
.
i_height
;
p_dec
->
fmt_out
.
video
.
i_height
=
p_sps
->
i_height
;
if
(
sps
.
vui
.
i_sar_num
!=
0
&&
sps
.
vui
.
i_sar_den
!=
0
)
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_num
=
p_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_den
=
p_sps
->
vui
.
i_sar_den
;
}
}
p_sys
->
i_log2_max_frame_num
=
sps
.
i_log2_max_frame_num
;
p_sys
->
i_log2_max_frame_num
=
p_sps
->
i_log2_max_frame_num
;
p_sys
->
b_frame_mbs_only
=
sps
.
b_frame_mbs_only
;
p_sys
->
b_frame_mbs_only
=
p_sps
->
b_frame_mbs_only
;
p_sys
->
i_pic_order_cnt_type
=
sps
.
i_pic_order_cnt_type
;
p_sys
->
i_pic_order_cnt_type
=
p_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_delta_pic_order_always_zero_flag
=
p_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_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
->
b_timing_info_present_flag
=
p_sps
->
vui
.
b_timing_info_present_flag
;
p_sys
->
i_num_units_in_tick
=
sps
.
vui
.
i_num_units_in_tick
;
p_sys
->
i_num_units_in_tick
=
p_sps
->
vui
.
i_num_units_in_tick
;
p_sys
->
i_time_scale
=
sps
.
vui
.
i_time_scale
;
p_sys
->
i_time_scale
=
p_sps
->
vui
.
i_time_scale
;
p_sys
->
b_fixed_frame_rate
=
sps
.
vui
.
b_fixed_frame_rate
;
p_sys
->
b_fixed_frame_rate
=
p_sps
->
vui
.
b_fixed_frame_rate
;
p_sys
->
b_pic_struct_present_flag
=
sps
.
vui
.
b_pic_struct_present_flag
;
p_sys
->
b_pic_struct_present_flag
=
p_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
->
b_cpb_dpb_delays_present_flag
=
p_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_cpb_removal_delay_length_minus1
=
p_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
->
i_dpb_output_delay_length_minus1
=
p_sps
->
vui
.
i_dpb_output_delay_length_minus1
;
}
}
/* We have a new SPS */
/* We have a new SPS */
if
(
!
p_sys
->
b_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
;
p_sys
->
b_sps
=
true
;
if
(
p_sys
->
pp_sps
[
sps
.
i_id
]
)
if
(
p_sys
->
pp_sps
[
p_sps
->
i_id
]
)
block_Release
(
p_sys
->
pp_sps
[
sps
.
i_id
]
);
block_Release
(
p_sys
->
pp_sps
[
p_sps
->
i_id
]
);
p_sys
->
pp_sps
[
sps
.
i_id
]
=
p_frag
;
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
)
static
void
PutPPS
(
decoder_t
*
p_dec
,
block_t
*
p_frag
)
{
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
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
);
block_Release
(
p_frag
);
return
;
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 */
/* We have a new PPS */
if
(
!
p_sys
->
b_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
;
p_sys
->
b_pps
=
true
;
if
(
p_sys
->
pp_pps
[
pps
.
i_id
]
)
if
(
p_sys
->
pp_pps
[
p_pps
->
i_id
]
)
block_Release
(
p_sys
->
pp_pps
[
pps
.
i_id
]
);
block_Release
(
p_sys
->
pp_pps
[
p_pps
->
i_id
]
);
p_sys
->
pp_pps
[
pps
.
i_id
]
=
p_frag
;
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
,
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,
...
@@ -399,30 +399,24 @@ int h264_get_spspps( uint8_t *p_buf, size_t i_buf,
return
0
;
return
0
;
}
}
int
h264_parse_sps
(
const
uint8_t
*
p_sps_buf
,
int
i_sps_size
,
void
h264_release_sps
(
h264_sequence_parameter_set_t
*
p_sps
)
struct
h264_nal_sps
*
p_sps
)
{
{
bs_t
s
;
free
(
p_sps
);
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
)
);
bs_init
(
&
s
,
&
p_sps_buf
[
5
],
i_sps_size
-
5
);
static
bool
h264_parse_sequence_parameter_set_rbsp
(
bs_t
*
p_bs
,
unsigned
i_bitflow
=
0
;
h264_sequence_parameter_set_t
*
p_sps
)
s
.
p_fwpriv
=
&
i_bitflow
;
{
s
.
pf_forward
=
hxxx_bsfw_ep3b_to_rbsp
;
/* Does the emulated 3bytes conversion to rbsp */
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
=
i_profile_idc
;
p_sps
->
i_profile_compatibility
=
bs_read
(
&
s
,
8
);
p_sps
->
i_profile_compatibility
=
bs_read
(
p_b
s
,
8
);
p_sps
->
i_level
=
bs_read
(
&
s
,
8
);
p_sps
->
i_level
=
bs_read
(
p_b
s
,
8
);
/* sps id */
/* 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
)
if
(
p_sps
->
i_id
>=
H264_SPS_MAX
)
return
-
1
;
return
false
;
if
(
i_profile_idc
==
PROFILE_H264_HIGH
||
if
(
i_profile_idc
==
PROFILE_H264_HIGH
||
i_profile_idc
==
PROFILE_H264_HIGH_10
||
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,
...
@@ -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
)
i_profile_idc
==
PROFILE_H264_MFC_HIGH
)
{
{
/* chroma_format_idc */
/* 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
)
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 */
/* bit_depth_luma_minus8 */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* bit_depth_chroma_minus8 */
/* bit_depth_chroma_minus8 */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* qpprime_y_zero_transform_bypass_flag */
/* qpprime_y_zero_transform_bypass_flag */
bs_skip
(
&
s
,
1
);
bs_skip
(
p_b
s
,
1
);
/* seq_scaling_matrix_present_flag */
/* seq_scaling_matrix_present_flag */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
if
(
i_tmp
)
{
{
for
(
int
i
=
0
;
i
<
((
3
!=
i_chroma_format_idc
)
?
8
:
12
);
i
++
)
for
(
int
i
=
0
;
i
<
((
3
!=
i_chroma_format_idc
)
?
8
:
12
);
i
++
)
{
{
/* seq_scaling_list_present_flag[i] */
/* seq_scaling_list_present_flag[i] */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
!
i_tmp
)
if
(
!
i_tmp
)
continue
;
continue
;
const
int
i_size_of_scaling_list
=
(
i
<
6
)
?
16
:
64
;
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,
...
@@ -467,7 +461,7 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
if
(
i_nextscale
!=
0
)
if
(
i_nextscale
!=
0
)
{
{
/* delta_scale */
/* delta_scale */
i_tmp
=
bs_read_se
(
&
s
);
i_tmp
=
bs_read_se
(
p_b
s
);
i_nextscale
=
(
i_lastscale
+
i_tmp
+
256
)
%
256
;
i_nextscale
=
(
i_lastscale
+
i_tmp
+
256
)
%
256
;
/* useDefaultScalingMatrixFlag = ... */
/* useDefaultScalingMatrixFlag = ... */
}
}
...
@@ -479,15 +473,15 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
...
@@ -479,15 +473,15 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
}
}
/* Skip i_log2_max_frame_num */
/* 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
)
if
(
p_sps
->
i_log2_max_frame_num
>
12
)
p_sps
->
i_log2_max_frame_num
=
12
;
p_sps
->
i_log2_max_frame_num
=
12
;
/* Read poc_type */
/* 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
)
if
(
p_sps
->
i_pic_order_cnt_type
==
0
)
{
{
/* skip i_log2_max_poc_lsb */
/* 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
)
if
(
p_sps
->
i_log2_max_pic_order_cnt_lsb
>
12
)
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,
...
@@ -495,61 +489,61 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
{
{
int
i_cycle
;
int
i_cycle
;
/* skip b_delta_pic_order_always_zero */
/* 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 */
/* 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 */
/* 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 */
/* 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
;
if
(
i_cycle
>
256
)
i_cycle
=
256
;
while
(
i_cycle
>
0
)
while
(
i_cycle
>
0
)
{
{
/* skip i_offset_for_ref_frame */
/* skip i_offset_for_ref_frame */
bs_read_se
(
&
s
);
bs_read_se
(
p_b
s
);
i_cycle
--
;
i_cycle
--
;
}
}
}
}
/* i_num_ref_frames */
/* i_num_ref_frames */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* b_gaps_in_frame_num_value_allowed */
/* b_gaps_in_frame_num_value_allowed */
bs_skip
(
&
s
,
1
);
bs_skip
(
p_b
s
,
1
);
/* Read size */
/* Read size */
p_sps
->
i_width
=
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
(
&
s
)
+
1
);
p_sps
->
i_height
=
16
*
(
bs_read_ue
(
p_b
s
)
+
1
);
/* b_frame_mbs_only */
/* 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
);
p_sps
->
i_height
*=
(
2
-
p_sps
->
b_frame_mbs_only
);
if
(
p_sps
->
b_frame_mbs_only
==
0
)
if
(
p_sps
->
b_frame_mbs_only
==
0
)
{
{
bs_skip
(
&
s
,
1
);
bs_skip
(
p_b
s
,
1
);
}
}
/* b_direct8x8_inference */
/* b_direct8x8_inference */
bs_skip
(
&
s
,
1
);
bs_skip
(
p_b
s
,
1
);
/* crop */
/* crop */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
if
(
i_tmp
)
{
{
/* left */
/* left */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* right */
/* right */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* top */
/* top */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
/* bottom */
/* bottom */
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
}
}
/* vui */
/* vui */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
if
(
i_tmp
)
{
{
p_sps
->
vui
.
b_valid
=
true
;
p_sps
->
vui
.
b_valid
=
true
;
/* read the aspect ratio part if any */
/* read the aspect ratio part if any */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
if
(
i_tmp
)
{
{
static
const
struct
{
int
w
,
h
;
}
sar
[
17
]
=
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,
...
@@ -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
},
{
64
,
33
},
{
160
,
99
},
{
4
,
3
},
{
3
,
2
},
{
2
,
1
},
{
2
,
1
},
};
};
int
i_sar
=
bs_read
(
&
s
,
8
);
int
i_sar
=
bs_read
(
p_b
s
,
8
);
int
w
,
h
;
int
w
,
h
;
if
(
i_sar
<
17
)
if
(
i_sar
<
17
)
...
@@ -570,8 +564,8 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
...
@@ -570,8 +564,8 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
}
}
else
if
(
i_sar
==
255
)
else
if
(
i_sar
==
255
)
{
{
w
=
bs_read
(
&
s
,
16
);
w
=
bs_read
(
p_b
s
,
16
);
h
=
bs_read
(
&
s
,
16
);
h
=
bs_read
(
p_b
s
,
16
);
}
}
else
else
{
{
...
@@ -592,97 +586,125 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
...
@@ -592,97 +586,125 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
}
}
/* overscan */
/* overscan */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
if
(
i_tmp
)
bs_read
(
&
s
,
1
);
bs_read
(
p_b
s
,
1
);
/* video signal type */
/* video signal type */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
if
(
i_tmp
)
{
{
bs_read
(
&
s
,
4
);
bs_read
(
p_b
s
,
4
);
/* colour desc */
/* colour desc */
bs_read
(
&
s
,
1
);
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
if
(
i_tmp
)
bs_read
(
&
s
,
24
);
bs_read
(
p_b
s
,
24
);
}
}
/* chroma loc info */
/* chroma loc info */
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
if
(
i_tmp
)
{
{
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
}
}
/* timing info */
/* 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
)
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_num_units_in_tick
=
bs_read
(
p_b
s
,
32
);
p_sps
->
vui
.
i_time_scale
=
bs_read
(
&
s
,
32
);
p_sps
->
vui
.
i_time_scale
=
bs_read
(
p_b
s
,
32
);
p_sps
->
vui
.
b_fixed_frame_rate
=
bs_read
(
&
s
,
1
);
p_sps
->
vui
.
b_fixed_frame_rate
=
bs_read
(
p_b
s
,
1
);
}
}
/* Nal hrd & VC1 hrd parameters */
/* Nal hrd & VC1 hrd parameters */
p_sps
->
vui
.
b_cpb_dpb_delays_present_flag
=
false
;
p_sps
->
vui
.
b_cpb_dpb_delays_present_flag
=
false
;
for
(
int
i
=
0
;
i
<
2
;
i
++
)
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
{
i_tmp
=
bs_read
(
&
s
,
1
);
i_tmp
=
bs_read
(
p_b
s
,
1
);
if
(
i_tmp
)
if
(
i_tmp
)
{
{
p_sps
->
vui
.
b_cpb_dpb_delays_present_flag
=
true
;
p_sps
->
vui
.
b_cpb_dpb_delays_present_flag
=
true
;
uint32_t
count
=
bs_read_ue
(
&
s
)
+
1
;
uint32_t
count
=
bs_read_ue
(
p_b
s
)
+
1
;
bs_read
(
&
s
,
4
);
bs_read
(
p_b
s
,
4
);
bs_read
(
&
s
,
4
);
bs_read
(
p_b
s
,
4
);
for
(
uint32_t
i
=
0
;
i
<
count
;
i
++
)
for
(
uint32_t
i
=
0
;
i
<
count
;
i
++
)
{
{
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
bs_read_ue
(
&
s
);
bs_read_ue
(
p_b
s
);
bs_read
(
&
s
,
1
);
bs_read
(
p_b
s
,
1
);
}
}
bs_read
(
&
s
,
5
);
bs_read
(
p_b
s
,
5
);
p_sps
->
vui
.
i_cpb_removal_delay_length_minus1
=
bs_read
(
&
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
(
&
s
,
5
);
p_sps
->
vui
.
i_dpb_output_delay_length_minus1
=
bs_read
(
p_b
s
,
5
);
bs_read
(
&
s
,
5
);
bs_read
(
p_b
s
,
5
);
}
}
}
}
if
(
p_sps
->
vui
.
b_cpb_dpb_delays_present_flag
)
if
(
p_sps
->
vui
.
b_cpb_dpb_delays_present_flag
)
bs_read
(
&
s
,
1
);
bs_read
(
p_b
s
,
1
);
/* pic struct info */
/* 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 */
/* + unparsed remains */
}
}
return
0
;
return
true
;
}
}
int
h264_parse_pps
(
const
uint8_t
*
p_pps_buf
,
int
i_pps_size
,
void
h264_release_pps
(
h264_picture_parameter_set_t
*
p_pps
)
struct
h264_nal_pps
*
p_pps
)
{
{
bs_t
s
;
free
(
p_pps
);
}
if
(
i_pps_size
<
5
||
(
p_pps_buf
[
4
]
&
0x1f
)
!=
H264_NAL_PPS
)
return
-
1
;
memset
(
p_pps
,
0
,
sizeof
(
struct
h264_nal_pps
)
);
static
bool
h264_parse_picture_parameter_set_rbsp
(
bs_t
*
p_bs
,
bs_init
(
&
s
,
&
p_pps_buf
[
5
],
i_pps_size
-
5
);
h264_picture_parameter_set_t
*
p_pps
)
p_pps
->
i_id
=
bs_read_ue
(
&
s
);
// pps id
{
p_pps
->
i_sps_id
=
bs_read_ue
(
&
s
);
// sps id
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
)
if
(
p_pps
->
i_id
>=
H264_PPS_MAX
||
p_pps
->
i_sps_id
>=
H264_SPS_MAX
)
{
return
false
;
return
-
1
;
}
bs_skip
(
p_bs
,
1
);
// entropy coding mode flag
bs_skip
(
&
s
,
1
);
// entropy coding mode flag
p_pps
->
i_pic_order_present_flag
=
bs_read
(
p_bs
,
1
);
p_pps
->
i_pic_order_present_flag
=
bs_read
(
&
s
,
1
);
/* TODO */
/* 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
,
block_t
*
h264_AnnexB_NAL_to_avcC
(
uint8_t
i_nal_length_size
,
const
uint8_t
*
p_sps_buf
,
const
uint8_t
*
p_sps_buf
,
size_t
i_sps_size
,
size_t
i_sps_size
,
...
...
modules/packetizer/h264_nal.h
View file @
0da5762a
...
@@ -72,7 +72,16 @@ enum h264_sei_type_e
...
@@ -72,7 +72,16 @@ enum h264_sei_type_e
H264_SEI_RECOVERY_POINT
=
6
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_id
;
int
i_profile
,
i_profile_compatibility
,
i_level
;
int
i_profile
,
i_profile_compatibility
,
i_level
;
...
@@ -97,7 +106,7 @@ struct h264_nal_sps
...
@@ -97,7 +106,7 @@ struct h264_nal_sps
}
vui
;
}
vui
;
};
};
struct
h264_
nal_pps
struct
h264_
picture_parameter_set_t
{
{
int
i_id
;
int
i_id
;
int
i_sps_id
;
int
i_sps_id
;
...
@@ -130,16 +139,6 @@ int h264_get_spspps( uint8_t *p_buf, size_t i_buf,
...
@@ -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_sps
,
size_t
*
p_sps_size
,
uint8_t
**
pp_pps
,
size_t
*
p_pps_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
/* Create a AVCDecoderConfigurationRecord from SPS/PPS
* Returns a valid block_t on success, must be freed with block_Release */
* 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
,
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