codec/h264/h264dec: fixed newRefPicListModification

This commit is contained in:
Saxon 2019-08-04 12:59:13 +09:30
parent 3f1c09a671
commit a94109e286
1 changed files with 49 additions and 60 deletions

View File

@ -37,11 +37,10 @@ type Slice struct {
// (defined in 7.3.3.1 of specifications) and a ref_pic_list_mvc_modification
// (defined in H.7.3.3.1.1 of specifications).
type RefPicListModification struct {
RefPicListModificationFlagL0 bool
ModificationOfPicNums int
AbsDiffPicNumMinus1 int
LongTermPicNum int
RefPicListModificationFlagL1 bool
RefPicListModificationFlag [2]bool
ModificationOfPicNums [2][]int
AbsDiffPicNumMinus1 [2][]int
LongTermPicNum [2][]int
}
// TODO: need to complete this.
@ -55,68 +54,57 @@ func NewRefPicListMVCModifiation(br *bits.BitReader) (*RefPicListModification, e
// NewRefPicListModification parses elements of a ref_pic_list_modification
// following the syntax structure defined in section 7.3.3.1, and returns as
// a new RefPicListModification.
func NewRefPicListModification(br *bits.BitReader, h *SliceHeader) (*RefPicListModification, error) {
func NewRefPicListModification(br *bits.BitReader, p *PPS, s *SliceHeader) (*RefPicListModification, error) {
r := &RefPicListModification{}
r.ModificationOfPicNums[0] = make([]int, p.NumRefIdxL0DefaultActiveMinus1+2)
r.ModificationOfPicNums[1] = make([]int, p.NumRefIdxL1DefaultActiveMinus1+2)
r.AbsDiffPicNumMinus1[0] = make([]int, p.NumRefIdxL1DefaultActiveMinus1+2)
r.AbsDiffPicNumMinus1[1] = make([]int, p.NumRefIdxL1DefaultActiveMinus1+2)
r.LongTermPicNum[0] = make([]int, p.NumRefIdxL1DefaultActiveMinus1+2)
r.LongTermPicNum[1] = make([]int, p.NumRefIdxL1DefaultActiveMinus1+2)
fr := newFieldReader(br)
// 7.3.3.1
if h.SliceType%5 != 2 && h.SliceType%5 != 4 {
b, err := br.ReadBits(1)
if err != nil {
return nil, errors.Wrap(err, "could not read RefPicListModificationFlagL0")
}
r.RefPicListModificationFlagL0 = b == 1
if s.SliceType%5 != 2 && s.SliceType%5 != 4 {
r.RefPicListModificationFlag[0] = fr.readBits(1) == 1
if r.RefPicListModificationFlagL0 {
for r.ModificationOfPicNums != 3 {
r.ModificationOfPicNums, err = readUe(br)
if err != nil {
return nil, errors.Wrap(err, "could not parse ModificationOfPicNums")
if r.RefPicListModificationFlag[0] {
for i := 0; ; i++ {
r.ModificationOfPicNums[0][i] = fr.readUe()
if r.ModificationOfPicNums[0][i] == 0 || r.ModificationOfPicNums[0][i] == 1 {
r.AbsDiffPicNumMinus1[0][i] = fr.readUe()
} else if r.ModificationOfPicNums[0][i] == 2 {
r.LongTermPicNum[0][i] = fr.readUe()
}
if r.ModificationOfPicNums == 0 || r.ModificationOfPicNums == 1 {
r.AbsDiffPicNumMinus1, err = readUe(br)
if err != nil {
return nil, errors.Wrap(err, "could not parse AbsDiffPicNumMinus1")
}
} else if r.ModificationOfPicNums == 2 {
r.LongTermPicNum, err = readUe(br)
if err != nil {
return nil, errors.Wrap(err, "could not parse LongTermPicNum")
if r.ModificationOfPicNums[0][i] == 3 {
break
}
}
}
}
}
if h.SliceType%5 == 1 {
b, err := br.ReadBits(1)
if err != nil {
return nil, errors.Wrap(err, "could not read RefPicListModificationFlagL1")
}
r.RefPicListModificationFlagL1 = b == 1
if s.SliceType%5 == 1 {
r.RefPicListModificationFlag[1] = fr.readBits(1) == 1
if r.RefPicListModificationFlagL1 {
for r.ModificationOfPicNums != 3 {
r.ModificationOfPicNums, err = readUe(br)
if err != nil {
return nil, errors.Wrap(err, "could not parse ModificationOfPicNums")
if r.RefPicListModificationFlag[1] {
for i := 0; ; i++ {
r.ModificationOfPicNums[1][i] = fr.readUe()
if r.ModificationOfPicNums[1][i] == 0 || r.ModificationOfPicNums[1][i] == 1 {
r.AbsDiffPicNumMinus1[1][i] = fr.readUe()
} else if r.ModificationOfPicNums[1][i] == 2 {
r.LongTermPicNum[1][i] = fr.readUe()
}
if r.ModificationOfPicNums == 0 || r.ModificationOfPicNums == 1 {
r.AbsDiffPicNumMinus1, err = readUe(br)
if err != nil {
return nil, errors.Wrap(err, "could not parse AbsDiffPicNumMinus1")
}
} else if r.ModificationOfPicNums == 2 {
r.LongTermPicNum, err = readUe(br)
if err != nil {
return nil, errors.Wrap(err, "could not parse LongTermPicNum")
if r.ModificationOfPicNums[1][i] == 3 {
break
}
}
}
}
}
// refPicListModification()
return nil, nil
return r, nil
}
// PredWeightTable provides elements of a pred_weight_table syntax structure
@ -262,6 +250,7 @@ type DecRefPicMarking struct {
AdaptiveRefPicMarkingModeFlag bool
MemoryManagementControlOperation int
DifferenceOfPicNumsMinus1 int
LongTermPicNum int
LongTermFrameIdx int
MaxLongTermFrameIdxPlus1 int
}
@ -303,7 +292,7 @@ func NewDecRefPicMarking(br *bits.BitReader, idrPic bool, h *SliceHeader) (*DecR
}
}
if d.MemoryManagementControlOperation == 2 {
h.RefPicListModification.LongTermPicNum, err = readUe(br)
d.LongTermPicNum, err = readUe(br)
if err != nil {
return nil, errors.Wrap(err, "could not parse LongTermPicNum")
}
@ -1345,7 +1334,7 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh
// H.7.3.3.1.1
// refPicListMvcModifications()
} else {
header.RefPicListModification, err = NewRefPicListModification(br, &header)
header.RefPicListModification, err = NewRefPicListModification(br, pps, &header)
if err != nil {
return nil, errors.Wrap(err, "could not parse RefPicListModification")
}