mirror of
https://github.com/Monibuca/engine.git
synced 2025-09-27 04:46:03 +08:00
229 lines
5.2 KiB
Go
229 lines
5.2 KiB
Go
package codec
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/deepch/vdk/codec/h265parser"
|
|
"m7s.live/engine/v4/util/bits"
|
|
)
|
|
|
|
type SPSInfo struct {
|
|
ProfileIdc uint
|
|
LevelIdc uint
|
|
|
|
MbWidth uint
|
|
MbHeight uint
|
|
|
|
CropLeft uint
|
|
CropRight uint
|
|
CropTop uint
|
|
CropBottom uint
|
|
|
|
Width uint
|
|
Height uint
|
|
}
|
|
|
|
func ParseSPS(data []byte) (self SPSInfo, err error) {
|
|
r := &bits.GolombBitReader{R: bytes.NewReader(data)}
|
|
|
|
if _, err = r.ReadBits(8); err != nil {
|
|
return
|
|
}
|
|
|
|
if self.ProfileIdc, err = r.ReadBits(8); err != nil {
|
|
return
|
|
}
|
|
|
|
// constraint_set0_flag-constraint_set6_flag,reserved_zero_2bits
|
|
if _, err = r.ReadBits(8); err != nil {
|
|
return
|
|
}
|
|
|
|
// level_idc
|
|
if self.LevelIdc, err = r.ReadBits(8); err != nil {
|
|
return
|
|
}
|
|
|
|
// seq_parameter_set_id
|
|
if _, 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 {
|
|
|
|
var chroma_format_idc uint
|
|
if chroma_format_idc, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
|
|
if chroma_format_idc == 3 {
|
|
// residual_colour_transform_flag
|
|
if _, err = r.ReadBit(); err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
// bit_depth_luma_minus8
|
|
if _, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
// bit_depth_chroma_minus8
|
|
if _, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
// qpprime_y_zero_transform_bypass_flag
|
|
if _, err = r.ReadBit(); err != nil {
|
|
return
|
|
}
|
|
|
|
var seq_scaling_matrix_present_flag uint
|
|
if seq_scaling_matrix_present_flag, err = r.ReadBit(); err != nil {
|
|
return
|
|
}
|
|
|
|
if seq_scaling_matrix_present_flag != 0 {
|
|
for i := 0; i < 8; i++ {
|
|
var seq_scaling_list_present_flag uint
|
|
if seq_scaling_list_present_flag, err = r.ReadBit(); err != nil {
|
|
return
|
|
}
|
|
if seq_scaling_list_present_flag != 0 {
|
|
var sizeOfScalingList uint
|
|
if i < 6 {
|
|
sizeOfScalingList = 16
|
|
} else {
|
|
sizeOfScalingList = 64
|
|
}
|
|
lastScale := uint(8)
|
|
nextScale := uint(8)
|
|
for j := uint(0); j < sizeOfScalingList; j++ {
|
|
if nextScale != 0 {
|
|
var delta_scale uint
|
|
if delta_scale, err = r.ReadSE(); err != nil {
|
|
return
|
|
}
|
|
nextScale = (lastScale + delta_scale + 256) % 256
|
|
}
|
|
if nextScale != 0 {
|
|
lastScale = nextScale
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// log2_max_frame_num_minus4
|
|
if _, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
|
|
var pic_order_cnt_type uint
|
|
if pic_order_cnt_type, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
if pic_order_cnt_type == 0 {
|
|
// log2_max_pic_order_cnt_lsb_minus4
|
|
if _, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
} else if pic_order_cnt_type == 1 {
|
|
// delta_pic_order_always_zero_flag
|
|
if _, err = r.ReadBit(); err != nil {
|
|
return
|
|
}
|
|
// offset_for_non_ref_pic
|
|
if _, err = r.ReadSE(); err != nil {
|
|
return
|
|
}
|
|
// offset_for_top_to_bottom_field
|
|
if _, err = r.ReadSE(); err != nil {
|
|
return
|
|
}
|
|
var num_ref_frames_in_pic_order_cnt_cycle uint
|
|
if num_ref_frames_in_pic_order_cnt_cycle, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
for i := uint(0); i < num_ref_frames_in_pic_order_cnt_cycle; i++ {
|
|
if _, err = r.ReadSE(); err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// max_num_ref_frames
|
|
if _, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
|
|
// gaps_in_frame_num_value_allowed_flag
|
|
if _, err = r.ReadBit(); err != nil {
|
|
return
|
|
}
|
|
|
|
if self.MbWidth, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
self.MbWidth++
|
|
|
|
if self.MbHeight, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
self.MbHeight++
|
|
|
|
var frame_mbs_only_flag uint
|
|
if frame_mbs_only_flag, err = r.ReadBit(); err != nil {
|
|
return
|
|
}
|
|
if frame_mbs_only_flag == 0 {
|
|
// mb_adaptive_frame_field_flag
|
|
if _, err = r.ReadBit(); err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
// direct_8x8_inference_flag
|
|
if _, err = r.ReadBit(); err != nil {
|
|
return
|
|
}
|
|
|
|
var frame_cropping_flag uint
|
|
if frame_cropping_flag, err = r.ReadBit(); err != nil {
|
|
return
|
|
}
|
|
if frame_cropping_flag != 0 {
|
|
if self.CropLeft, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
if self.CropRight, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
if self.CropTop, err = r.ReadExponentialGolombCode(); err != nil {
|
|
return
|
|
}
|
|
if self.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
|
|
|
|
return
|
|
}
|
|
|
|
func ParseHevcSPS(data []byte) (self SPSInfo, err error) {
|
|
var rawsps h265parser.SPSInfo
|
|
if rawsps, err = h265parser.ParseSPS(data); err == nil {
|
|
self.CropLeft, self.CropRight, self.CropTop, self.CropBottom = uint(rawsps.CropLeft), uint(rawsps.CropRight), uint(rawsps.CropTop), uint(rawsps.CropBottom)
|
|
self.ProfileIdc, self.LevelIdc = rawsps.ProfileIdc, rawsps.LevelIdc
|
|
self.MbWidth, self.MbHeight = rawsps.MbWidth, rawsps.MbHeight
|
|
self.Width = uint(rawsps.Width)
|
|
self.Height = uint(rawsps.Height)
|
|
}
|
|
return
|
|
}
|