This commit is contained in:
Andrey Semochkin
2021-05-08 23:07:59 +03:00
parent 338966ed52
commit 5adbbcc01f
5 changed files with 190 additions and 22 deletions

View File

@@ -3,6 +3,7 @@ package h264parser
import (
"bytes"
"fmt"
"math"
"github.com/deepch/vdk/av"
"github.com/deepch/vdk/utils/bits"
@@ -294,8 +295,10 @@ func SplitNALUs(b []byte) (nalus [][]byte, typ int) {
}
type SPSInfo struct {
ProfileIdc uint
LevelIdc uint
Id uint
ProfileIdc uint
LevelIdc uint
ConstraintSetFlag uint
MbWidth uint
MbHeight uint
@@ -307,38 +310,59 @@ type SPSInfo struct {
Width uint
Height uint
FPS uint
}
func ParseSPS(data []byte) (self SPSInfo, err error) {
func RemoveH264orH265EmulationBytes(b []byte) []byte {
j := 0
r := make([]byte, len(b))
for i := 0; (i < len(b)) && (j < len(b)); {
if i+2 < len(b) &&
b[i] == 0 && b[i+1] == 0 && b[i+2] == 3 {
r[j] = 0
r[j+1] = 0
j = j + 2
i = i + 3
} else {
r[j] = b[i]
j = j + 1
i = i + 1
}
}
return r[:j]
}
func ParseSPS(data []byte) (s SPSInfo, err error) {
data = RemoveH264orH265EmulationBytes(data)
r := &bits.GolombBitReader{R: bytes.NewReader(data)}
if _, err = r.ReadBits(8); err != nil {
return
}
if self.ProfileIdc, err = r.ReadBits(8); err != nil {
if s.ProfileIdc, err = r.ReadBits(8); err != nil {
return
}
// constraint_set0_flag-constraint_set6_flag,reserved_zero_2bits
if _, err = r.ReadBits(8); err != nil {
if s.ConstraintSetFlag, err = r.ReadBits(8); err != nil {
return
}
s.ConstraintSetFlag = s.ConstraintSetFlag >> 2
// level_idc
if self.LevelIdc, err = r.ReadBits(8); err != nil {
if s.LevelIdc, err = r.ReadBits(8); err != nil {
return
}
// seq_parameter_set_id
if _, err = r.ReadExponentialGolombCode(); err != nil {
if s.Id, err = r.ReadExponentialGolombCode(); err != nil {
return
}
if self.ProfileIdc == 100 || self.ProfileIdc == 110 ||
self.ProfileIdc == 122 || self.ProfileIdc == 244 ||
self.ProfileIdc == 44 || self.ProfileIdc == 83 ||
self.ProfileIdc == 86 || self.ProfileIdc == 118 {
if s.ProfileIdc == 100 || s.ProfileIdc == 110 ||
s.ProfileIdc == 122 || s.ProfileIdc == 244 ||
s.ProfileIdc == 44 || s.ProfileIdc == 83 ||
s.ProfileIdc == 86 || s.ProfileIdc == 118 {
var chroma_format_idc uint
if chroma_format_idc, err = r.ReadExponentialGolombCode(); err != nil {
@@ -450,15 +474,15 @@ func ParseSPS(data []byte) (self SPSInfo, err error) {
return
}
if self.MbWidth, err = r.ReadExponentialGolombCode(); err != nil {
if s.MbWidth, err = r.ReadExponentialGolombCode(); err != nil {
return
}
self.MbWidth++
s.MbWidth++
if self.MbHeight, err = r.ReadExponentialGolombCode(); err != nil {
if s.MbHeight, err = r.ReadExponentialGolombCode(); err != nil {
return
}
self.MbHeight++
s.MbHeight++
var frame_mbs_only_flag uint
if frame_mbs_only_flag, err = r.ReadBit(); err != nil {
@@ -481,23 +505,146 @@ func ParseSPS(data []byte) (self SPSInfo, err error) {
return
}
if frame_cropping_flag != 0 {
if self.CropLeft, err = r.ReadExponentialGolombCode(); err != nil {
if s.CropLeft, err = r.ReadExponentialGolombCode(); err != nil {
return
}
if self.CropRight, err = r.ReadExponentialGolombCode(); err != nil {
if s.CropRight, err = r.ReadExponentialGolombCode(); err != nil {
return
}
if self.CropTop, err = r.ReadExponentialGolombCode(); err != nil {
if s.CropTop, err = r.ReadExponentialGolombCode(); err != nil {
return
}
if self.CropBottom, err = r.ReadExponentialGolombCode(); err != nil {
if s.CropBottom, err = r.ReadExponentialGolombCode(); err != nil {
return
}
}
self.Width = (self.MbWidth * 16) - self.CropLeft*2 - self.CropRight*2
self.Height = ((2 - frame_mbs_only_flag) * self.MbHeight * 16) - self.CropTop*2 - self.CropBottom*2
s.Width = (s.MbWidth * 16) - s.CropLeft*2 - s.CropRight*2
s.Height = ((2 - frame_mbs_only_flag) * s.MbHeight * 16) - s.CropTop*2 - s.CropBottom*2
vui_parameter_present_flag, err := r.ReadBit()
if err != nil {
return
}
if vui_parameter_present_flag != 0 {
aspect_ratio_info_present_flag, err := r.ReadBit()
if err != nil {
return s, err
}
if aspect_ratio_info_present_flag != 0 {
aspect_ratio_idc, err := r.ReadBits(8)
if err != nil {
return s, err
}
if aspect_ratio_idc == 255 {
sar_width, err := r.ReadBits(16)
if err != nil {
return s, err
}
sar_height, err := r.ReadBits(16)
if err != nil {
return s, err
}
_, _ = sar_width, sar_height
}
}
overscan_info_present_flag, err := r.ReadBit()
if err != nil {
return s, err
}
if overscan_info_present_flag != 0 {
overscan_appropriate_flagu, err := r.ReadBit()
if err != nil {
return s, err
}
_ = overscan_appropriate_flagu
}
video_signal_type_present_flag, err := r.ReadBit()
if video_signal_type_present_flag != 0 {
video_format, err := r.ReadBits(3)
if err != nil {
return s, err
}
_ = video_format
video_full_range_flag, err := r.ReadBit()
if err != nil {
return s, err
}
_ = video_full_range_flag
colour_description_present_flag, err := r.ReadBit()
if err != nil {
return s, err
}
if colour_description_present_flag != 0 {
colour_primaries, err := r.ReadBits(8)
if err != nil {
return s, err
}
_ = colour_primaries
transfer_characteristics, err := r.ReadBits(8)
if err != nil {
return s, err
}
_ = transfer_characteristics
matrix_coefficients, err := r.ReadBits(8)
if err != nil {
return s, err
}
_ = matrix_coefficients
}
}
chroma_loc_info_present_flag, err := r.ReadBit()
if err != nil {
return s, err
}
if chroma_loc_info_present_flag != 0 {
chroma_sample_loc_type_top_field, err := r.ReadSE()
if err != nil {
return s, err
}
_ = chroma_sample_loc_type_top_field
chroma_sample_loc_type_bottom_field, err := r.ReadSE()
if err != nil {
return s, err
}
_ = chroma_sample_loc_type_bottom_field
}
timing_info_present_flag, err := r.ReadBit()
if err != nil {
return s, err
}
if timing_info_present_flag != 0 {
num_units_in_tick, err := r.ReadBits(32)
if err != nil {
return s, err
}
time_scale, err := r.ReadBits(32)
if err != nil {
return s, err
}
s.FPS = uint(math.Floor(float64(time_scale) / float64(num_units_in_tick) / 2.0))
fixed_frame_rate_flag, err := r.ReadBit()
if err != nil {
return s, err
}
if fixed_frame_rate_flag != 0 {
//utils.L.InfoLn("fixed_frame_rate_flag", fixed_frame_rate_flag)
//have been devide 2
//self.FPS = self.FPS / 2
}
}
}
return
}