// 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/naza/pkg/nazaerrors" "github.com/q191201771/naza/pkg/bele" "github.com/q191201771/naza/pkg/nazabits" "github.com/q191201771/naza/pkg/nazabytes" "github.com/q191201771/naza/pkg/nazalog" ) func ParseSps(payload []byte, ctx *Context) error { br := nazabits.NewBitReader(payload) var sps Sps if err := parseSpsBasic(&br, &sps); err != nil { nazalog.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自身解析的问题 nazalog.Errorf("parseSpsGamma failed. err=%+v, payload=%s", err, hex.Dump(nazabytes.Prefix(payload, 128))) } nazalog.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 } // 尝试解析PPS所有字段,实验中,请勿直接使用该函数 func TryParsePps(payload []byte) error { // ISO-14496-10.pdf // 7.3.2.2 Picture parameter set RBSP syntax // TODO impl me return nil } // 尝试解析SeqHeader所有字段,实验中,请勿直接使用该函数 // // @param rtmp message的payload部分或者flv tag的payload部分 // 注意,包含了头部2字节类型以及3字节的cts // func TryParseSeqHeader(payload []byte) error { if len(payload) < 5 { return ErrAvc } if payload[0] != 0x17 || payload[1] != 0x00 || payload[2] != 0 || payload[3] != 0 || payload[4] != 0 { return 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) nazalog.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 //if t != 0x67 { // return Context{}, ErrAvc //} 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(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 } //func parseSpsBeta(br *nazabits.BitReader, sps *Sps) error { // var err error // // // 100 High profile // if sps.ProfileIdc == 100 { // sps.ChromaFormatIdc, err = br.ReadUeGolomb() // if err != nil { // return nazaerrors.Wrap(err) // } // if sps.ChromaFormatIdc > 3 { // return nazaerrors.Wrap(ErrAvc) // } // // if sps.ChromaFormatIdc == 3 { // sps.ResidualColorTransformFlag, err = br.ReadBits8(1) // 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 // // if sps.BitDepthChroma != sps.BitDepthLuma || sps.BitDepthChroma < 8 || sps.BitDepthChroma > 14 { // return nazaerrors.Wrap(ErrAvc) // } // // sps.TransFormBypass, err = br.ReadBits8(1) // if err != nil { // return nazaerrors.Wrap(err) // } // // // seq scaling matrix present // flag, err := br.ReadBits8(1) // if err != nil { // return nazaerrors.Wrap(err) // } // if flag == 1 { // nazalog.Debugf("scaling matrix present.") // // TODO chef: 还没有正确实现,只是针对特定case做了处理 // _, err = br.ReadBits32(128) // if err != nil { // return nazaerrors.Wrap(err) // } // } // } else { // sps.ChromaFormatIdc = 1 // sps.BitDepthLuma = 8 // sps.BitDepthChroma = 8 // } // // sps.Log2MaxFrameNumMinus4, err = br.ReadUeGolomb() // if err != nil { // return nazaerrors.Wrap(err) // } // if sps.Log2MaxFrameNumMinus4 > 12 { // return nazaerrors.Wrap(ErrAvc) // } // sps.PicOrderCntType, err = br.ReadUeGolomb() // if err != nil { // return nazaerrors.Wrap(err) // } // // if sps.PicOrderCntType == 0 { // sps.Log2MaxPicOrderCntLsb, err = br.ReadUeGolomb() // sps.Log2MaxPicOrderCntLsb += 4 // } else if sps.PicOrderCntType == 2 { // // noop // } else { // nazalog.Debugf("not impl yet. sps.PicOrderCntType=%d", sps.PicOrderCntType) // return nazaerrors.Wrap(ErrAvc) // } // // sps.NumRefFrames, err = br.ReadUeGolomb() // if err != nil { // return nazaerrors.Wrap(err) // } // sps.GapsInFrameNumValueAllowedFlag, err = br.ReadBits8(1) // if err != nil { // return nazaerrors.Wrap(err) // } // sps.PicWidthInMbsMinusOne, err = br.ReadUeGolomb() // if err != nil { // return nazaerrors.Wrap(err) // } // sps.PicHeightInMapUnitsMinusOne, err = br.ReadUeGolomb() // if 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) // if err != nil { // return nazaerrors.Wrap(err) // } // } // // sps.Direct8X8InferenceFlag, err = br.ReadBits8(1) // if err != nil { // return nazaerrors.Wrap(err) // } // // sps.FrameCroppingFlag, err = br.ReadBits8(1) // if err != nil { // return nazaerrors.Wrap(err) // } // if sps.FrameCroppingFlag == 1 { // sps.FrameCropLeftOffset, err = br.ReadUeGolomb() // if err != nil { // return nazaerrors.Wrap(err) // } // sps.FrameCropRightOffset, err = br.ReadUeGolomb() // if err != nil { // return nazaerrors.Wrap(err) // } // sps.FrameCropTopOffset, err = br.ReadUeGolomb() // if err != nil { // return nazaerrors.Wrap(err) // } // sps.FrameCropBottomOffset, err = br.ReadUeGolomb() // if err != nil { // return nazaerrors.Wrap(err) // } // } // // // TODO parse sps vui parameters // return nil //} //var defaultScaling4 = [][]uint8{ // { // 6, 13, 20, 28, 13, 20, 28, 32, // 20, 28, 32, 37, 28, 32, 37, 42, // }, // { // 10, 14, 20, 24, 14, 20, 24, 27, // 20, 24, 27, 30, 24, 27, 30, 34, // }, //} // //var defaultScaling8 = [][]uint8{ // { // 6, 10, 13, 16, 18, 23, 25, 27, // 10, 11, 16, 18, 23, 25, 27, 29, // 13, 16, 18, 23, 25, 27, 29, 31, // 16, 18, 23, 25, 27, 29, 31, 33, // 18, 23, 25, 27, 29, 31, 33, 36, // 23, 25, 27, 29, 31, 33, 36, 38, // 25, 27, 29, 31, 33, 36, 38, 40, // 27, 29, 31, 33, 36, 38, 40, 42, // }, // { // 9, 13, 15, 17, 19, 21, 22, 24, // 13, 13, 17, 19, 21, 22, 24, 25, // 15, 17, 19, 21, 22, 24, 25, 27, // 17, 19, 21, 22, 24, 25, 27, 28, // 19, 21, 22, 24, 25, 27, 28, 30, // 21, 22, 24, 25, 27, 28, 30, 32, // 22, 24, 25, 27, 28, 30, 32, 33, // 24, 25, 27, 28, 30, 32, 33, 35, // }, //} // //var ffZigzagDirect = []uint8{ // 0, 1, 8, 16, 9, 2, 3, 10, // 17, 24, 32, 25, 18, 11, 4, 5, // 12, 19, 26, 33, 40, 48, 41, 34, // 27, 20, 13, 6, 7, 14, 21, 28, // 35, 42, 49, 56, 57, 50, 43, 36, // 29, 22, 15, 23, 30, 37, 44, 51, // 58, 59, 52, 45, 38, 31, 39, 46, // 53, 60, 61, 54, 47, 55, 62, 63, //} // //var ffZigzagScan = []uint8{ // 0 + 0*4, 1 + 0*4, 0 + 1*4, 0 + 2*4, // 1 + 1*4, 2 + 0*4, 3 + 0*4, 2 + 1*4, // 1 + 2*4, 0 + 3*4, 1 + 3*4, 2 + 2*4, // 3 + 1*4, 3 + 2*4, 2 + 3*4, 3 + 3*4, //} // //func decodeScalingMatrices(reader *nazabits.BitReader) error { // // 6 * 16 // var spsScalingMatrix4 = [][]uint8{ // {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // } // // 6 * 64 // var spsScalingMatrix8 = [][]uint8{ // {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // } // // fallback := [][]uint8{defaultScaling4[0], defaultScaling4[1], defaultScaling8[0], defaultScaling8[1]} // decodeScalingList(reader, spsScalingMatrix4[0], 16, defaultScaling4[0], fallback[0]) // decodeScalingList(reader, spsScalingMatrix4[1], 16, defaultScaling4[0], spsScalingMatrix4[0]) // decodeScalingList(reader, spsScalingMatrix4[2], 16, defaultScaling4[0], spsScalingMatrix4[1]) // decodeScalingList(reader, spsScalingMatrix4[3], 16, defaultScaling4[1], fallback[1]) // decodeScalingList(reader, spsScalingMatrix4[4], 16, defaultScaling4[1], spsScalingMatrix4[3]) // decodeScalingList(reader, spsScalingMatrix4[4], 16, defaultScaling4[1], spsScalingMatrix4[3]) // // decodeScalingList(reader, spsScalingMatrix8[0], 64, defaultScaling8[0], fallback[2]) // decodeScalingList(reader, spsScalingMatrix8[3], 64, defaultScaling8[1], fallback[3]) // // return nil //} // //func decodeScalingList(reader *nazabits.BitReader, factors []uint8, size int, jvtList []uint8, fallbackList []uint8) error { // var ( // i = 0 // last = 8 // next = 8 // scan []uint8 // ) // if size == 16 { // scan = ffZigzagScan // } else { // scan = ffZigzagDirect // } // flag, err := reader.ReadBit() // if err != nil { // return err // } // return nil // if flag == 0 { // for n := 0; n < size; n++ { // factors[n] = fallbackList[n] // } // } else { // for i = 0; i < size; i++ { // if next != 0 { // v, err := reader.ReadUeGolomb() // if err != nil { // return err // } // next = (last + int(v)) & 0xff // } // if i == 0 && next == 0 { // for n := 0; n < size; n++ { // factors[n] = jvtList[n] // } // break // } // if next != 0 { // factors[scan[i]] = uint8(next) // last = next // } else { // factors[scan[i]] = uint8(last) // } // } // } // return nil //}