You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lal/pkg/avc/beta.go

358 lines
9.2 KiB
Go

// 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"
3 years ago
"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
}