// Copyright 2021, Chef. All rights reserved. // https://github.com/q191201771/lal // // Use of this source code is governed by a MIT-style license // that can be found in the License file. // // Author: Chef (191201771@qq.com) package avc import ( "encoding/hex" "github.com/q191201771/lal/pkg/base" "github.com/q191201771/naza/pkg/nazaerrors" "github.com/q191201771/naza/pkg/bele" "github.com/q191201771/naza/pkg/nazabits" "github.com/q191201771/naza/pkg/nazabytes" ) func ParseSps(payload []byte, ctx *Context) error { br := nazabits.NewBitReader(payload) var sps Sps if err := parseSpsBasic(&br, &sps); err != nil { Log.Errorf("parseSpsBasic failed. err=%+v, payload=%s", err, hex.Dump(nazabytes.Prefix(payload, 128))) return err } ctx.Profile = sps.ProfileIdc ctx.Level = sps.LevelIdc //if err := parseSpsBeta(&br, &sps); err != nil { // // 注意,这里不将错误返回给上层,因为可能是Beta自身解析的问题 //} if err := parseSpsGamma(&br, &sps); err != nil { // 注意,这里不将错误返回给上层,因为可能是Beta自身解析的问题 Log.Errorf("parseSpsGamma failed. err=%+v, payload=%s", err, hex.Dump(nazabytes.Prefix(payload, 128))) } Log.Debugf("sps=%+v", sps) ctx.Width = (sps.PicWidthInMbsMinusOne+1)*16 - (sps.FrameCropLeftOffset+sps.FrameCropRightOffset)*2 ctx.Height = (2-uint32(sps.FrameMbsOnlyFlag))*(sps.PicHeightInMapUnitsMinusOne+1)*16 - (sps.FrameCropTopOffset+sps.FrameCropBottomOffset)*2 return nil } // TryParsePps 尝试解析PPS所有字段,实验中,请勿直接使用该函数 func TryParsePps(payload []byte) error { // ISO-14496-10.pdf // 7.3.2.2 Picture parameter set RBSP syntax // TODO impl me return nil } // TryParseSeqHeader 尝试解析SeqHeader所有字段,实验中,请勿直接使用该函数。 // // @param payload: // rtmp message的payload部分或者flv tag的payload部分。 // 注意,包含了头部2字节类型以及3字节的cts。 func TryParseSeqHeader(payload []byte) error { if len(payload) < 5 { return nazaerrors.Wrap(base.ErrShortBuffer) } if payload[0] != 0x17 || payload[1] != 0x00 || payload[2] != 0 || payload[3] != 0 || payload[4] != 0 { return nazaerrors.Wrap(base.ErrAvc) } // H.264-AVC-ISO_IEC_14496-15.pdf // 5.2.4 Decoder configuration information var dcr DecoderConfigurationRecord var err error br := nazabits.NewBitReader(payload[5:]) // TODO check error dcr.ConfigurationVersion, err = br.ReadBits8(8) dcr.AvcProfileIndication, err = br.ReadBits8(8) dcr.ProfileCompatibility, err = br.ReadBits8(8) dcr.AvcLevelIndication, err = br.ReadBits8(8) _, err = br.ReadBits8(6) // reserved = '111111'b dcr.LengthSizeMinusOne, err = br.ReadBits8(2) _, err = br.ReadBits8(3) // reserved = '111'b dcr.NumOfSps, err = br.ReadBits8(5) b, err := br.ReadBytes(2) dcr.SpsLength = bele.BeUint16(b) _, _ = br.ReadBytes(uint(dcr.SpsLength)) _, err = br.ReadBits8(3) // reserved = '111'b dcr.NumOfPps, err = br.ReadBits8(5) b, err = br.ReadBytes(2) dcr.PpsLength = bele.BeUint16(b) Log.Debugf("%+v", dcr) // 5 + 5 + 1 + 2 var ctx Context _ = ParseSps(payload[13:13+dcr.SpsLength], &ctx) // 13 + 1 + 2 _ = TryParsePps(payload[16 : 16+dcr.PpsLength]) return err } func parseSpsBasic(br *nazabits.BitReader, sps *Sps) error { t, err := br.ReadBits8(8) //nalType SPS should be 0x67 if err != nil { return nazaerrors.Wrap(err) } _ = t sps.ProfileIdc, err = br.ReadBits8(8) if err != nil { return nazaerrors.Wrap(err) } sps.ConstraintSet0Flag, err = br.ReadBits8(1) if err != nil { return nazaerrors.Wrap(err) } sps.ConstraintSet1Flag, err = br.ReadBits8(1) if err != nil { return nazaerrors.Wrap(err) } sps.ConstraintSet2Flag, err = br.ReadBits8(1) if err != nil { return nazaerrors.Wrap(err) } _, err = br.ReadBits8(5) if err != nil { return nazaerrors.Wrap(err) } sps.LevelIdc, err = br.ReadBits8(8) if err != nil { return nazaerrors.Wrap(err) } sps.SpsId, err = br.ReadGolomb() if err != nil { return nazaerrors.Wrap(err) } if sps.SpsId >= 32 { return nazaerrors.Wrap(base.ErrAvc) } return nil } func parseSpsGamma(br *nazabits.BitReader, sps *Sps) (err error) { switch sps.ProfileIdc { case 100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 139, 134: sps.ChromaFormatIdc, err = br.ReadUeGolomb() // chroma_format_idc if err != nil { return nazaerrors.Wrap(err) } if sps.ChromaFormatIdc == 3 { sps.ResidualColorTransformFlag, err = br.ReadBits8(1) // separate_colour_plane_flag if err != nil { return nazaerrors.Wrap(err) } } sps.BitDepthLuma, err = br.ReadUeGolomb() if err != nil { return nazaerrors.Wrap(err) } sps.BitDepthLuma += 8 sps.BitDepthChroma, err = br.ReadUeGolomb() if err != nil { return nazaerrors.Wrap(err) } sps.BitDepthChroma += 8 sps.TransFormBypass, err = br.ReadBits8(1) // qpprime_y_zero_transform_bypass_flag if err != nil { return nazaerrors.Wrap(err) } flag, err := br.ReadBits8(1) // seq_scaling_matrix_present_flag if err != nil { return nazaerrors.Wrap(err) } if flag == 1 { loop := 8 if sps.ChromaFormatIdc == 3 { loop = 12 } deltaScale := 0 lastScale := 8 nextScale := 8 for i := 0; i < loop; i++ { flag, err := br.ReadBits8(1) // seq_scaling_list_present_flag if err != nil { return nazaerrors.Wrap(err) } if flag == 0 { continue } lastScale = 8 nextScale = 8 sizeOfScalingList := 16 if i >= 6 { sizeOfScalingList = 64 } for j := 0; j < sizeOfScalingList; j++ { if nextScale != 0 { v, err := br.ReadSeGolomb() if err != nil { return nazaerrors.Wrap(err) } deltaScale = int(v) nextScale = (lastScale + deltaScale) & 0xff } if nextScale != 0 { lastScale = nextScale } } } } default: sps.ChromaFormatIdc = 1 sps.BitDepthLuma = 8 sps.BitDepthChroma = 8 } sps.Log2MaxFrameNumMinus4, err = br.ReadUeGolomb() // log2_max_frame_num_minus4 if err != nil { return nazaerrors.Wrap(err) } sps.PicOrderCntType, err = br.ReadUeGolomb() if err != nil { return nazaerrors.Wrap(err) } if sps.PicOrderCntType == 0 { sps.Log2MaxPicOrderCntLsb, err = br.ReadUeGolomb() // log2_max_pic_order_cnt_lsb_minus4 if err != nil { return nazaerrors.Wrap(err) } sps.Log2MaxPicOrderCntLsb += 4 } else if sps.PicOrderCntType == 1 { _, _ = br.ReadBits8(1) // delta_pic_order_always_zero _, _ = br.ReadSeGolomb() // offset_for_non_ref_pic _, _ = br.ReadSeGolomb() // offset_for_top_to_bottom_field if br.Err() != nil { return nazaerrors.Wrap(err) } nrfipocc, err := br.ReadUeGolomb() // num_ref_frames_in_pic_order_cnt_cycle if err != nil { return nazaerrors.Wrap(err) } for i := 0; i < int(nrfipocc); i++ { _, err := br.ReadSeGolomb() // offset_for_ref_frame if err != nil { return nazaerrors.Wrap(err) } } } sps.NumRefFrames, _ = br.ReadUeGolomb() // max_num_ref_frames sps.GapsInFrameNumValueAllowedFlag, _ = br.ReadBits8(1) // gaps_in_frame_num_value_allowed_flag sps.PicWidthInMbsMinusOne, _ = br.ReadUeGolomb() // pic_width_in_mbs_minus1 sps.PicHeightInMapUnitsMinusOne, _ = br.ReadUeGolomb() // pic_height_in_map_units_minus1 if br.Err() != nil { return nazaerrors.Wrap(err) } sps.FrameMbsOnlyFlag, err = br.ReadBits8(1) if err != nil { return nazaerrors.Wrap(err) } if sps.FrameMbsOnlyFlag == 0 { sps.MbAdaptiveFrameFieldFlag, err = br.ReadBits8(1) // mb_adaptive_frame_field_flag if err != nil { return nazaerrors.Wrap(err) } } sps.Direct8X8InferenceFlag, err = br.ReadBits8(1) // direct_8x8_inference_flag if err != nil { return nazaerrors.Wrap(err) } sps.FrameCroppingFlag, err = br.ReadBits8(1) if err != nil { return nazaerrors.Wrap(err) } if sps.FrameCroppingFlag == 1 { // frame_cropping_flag sps.FrameCropLeftOffset, _ = br.ReadUeGolomb() // frame_crop_left_offset sps.FrameCropRightOffset, _ = br.ReadUeGolomb() // frame_crop_right_offset sps.FrameCropTopOffset, _ = br.ReadUeGolomb() // frame_crop_top_offset sps.FrameCropBottomOffset, _ = br.ReadUeGolomb() // frame_crop_bottom_offset if br.Err() != nil { return nazaerrors.Wrap(err) } } flag, err := br.ReadBits8(1) // vui_parameters_present_flag if err != nil { return nazaerrors.Wrap(err) } if flag == 1 { flag, err := br.ReadBits8(1) // aspect_ratio_info_present_flag if err != nil { return nazaerrors.Wrap(err) } if flag == 1 { ari, err := br.ReadBits8(8) // aspect_ratio_idc if err != nil { return nazaerrors.Wrap(err) } if ari == 0xff { v, err := br.ReadBits16(16) if err != nil { return nazaerrors.Wrap(err) } sps.SarNum = int(v) v, err = br.ReadBits16(16) if err != nil { return nazaerrors.Wrap(err) } sps.SarDen = int(v) } else if ari < 17 { mapping := []struct { num int den int }{ {0, 1}, {1, 1}, {12, 11}, {10, 11}, {16, 11}, {40, 33}, {24, 11}, {20, 11}, {32, 11}, {80, 33}, {18, 11}, {15, 11}, {64, 33}, {160, 99}, {4, 3}, {3, 2}, {2, 1}, } sps.SarNum = mapping[ari].num sps.SarDen = mapping[ari].den } } } if sps.SarDen == 0 { sps.SarNum = 1 sps.SarDen = 1 } return nil }