123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- package codec
- import (
- "bytes"
- "github.com/cnotch/ipchub/av/codec/hevc"
- "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 hevc.H265RawSPS
- if err = rawsps.Decode(data); err == nil {
- self.CropLeft, self.CropRight, self.CropTop, self.CropBottom = uint(rawsps.Conf_win_left_offset), uint(rawsps.Conf_win_right_offset), uint(rawsps.Conf_win_top_offset), uint(rawsps.Conf_win_bottom_offset)
- self.Width = uint(rawsps.Pic_width_in_luma_samples)
- self.Height = uint(rawsps.Pic_height_in_luma_samples)
- }
- return
- }
|