From a94109e2867f44ac6db1fc50e08c4f3fd3e7fa48 Mon Sep 17 00:00:00 2001 From: Saxon Date: Sun, 4 Aug 2019 12:59:13 +0930 Subject: [PATCH 1/9] codec/h264/h264dec: fixed newRefPicListModification --- codec/h264/h264dec/slice.go | 109 ++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 60 deletions(-) diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index 18fb7a69..63af7da3 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -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 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 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.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 } } } } - // refPicListModification() - return nil, nil + + if s.SliceType%5 == 1 { + r.RefPicListModificationFlag[1] = fr.readBits(1) == 1 + + 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[1][i] == 3 { + break + } + } + } + } + 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") } From 21603750aa6f88b6d61e9881f21177d84a4da10c Mon Sep 17 00:00:00 2001 From: Saxon Date: Sun, 4 Aug 2019 13:40:53 +0930 Subject: [PATCH 2/9] codec/h264/h264dec/slice_test.go: added TestNewRefPicListModification with a single test --- codec/h264/h264dec/slice.go | 4 +- codec/h264/h264dec/slice_test.go | 69 +++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index 63af7da3..6930c89c 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -58,9 +58,9 @@ func NewRefPicListModification(br *bits.BitReader, p *PPS, s *SliceHeader) (*Ref 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[0] = make([]int, p.NumRefIdxL0DefaultActiveMinus1+2) r.AbsDiffPicNumMinus1[1] = make([]int, p.NumRefIdxL1DefaultActiveMinus1+2) - r.LongTermPicNum[0] = make([]int, p.NumRefIdxL1DefaultActiveMinus1+2) + r.LongTermPicNum[0] = make([]int, p.NumRefIdxL0DefaultActiveMinus1+2) r.LongTermPicNum[1] = make([]int, p.NumRefIdxL1DefaultActiveMinus1+2) fr := newFieldReader(br) diff --git a/codec/h264/h264dec/slice_test.go b/codec/h264/h264dec/slice_test.go index e7988a7e..59f8314b 100644 --- a/codec/h264/h264dec/slice_test.go +++ b/codec/h264/h264dec/slice_test.go @@ -1,6 +1,12 @@ package h264dec -import "testing" +import ( + "bytes" + "reflect" + "testing" + + "bitbucket.org/ausocean/av/codec/h264/h264dec/bits" +) var subWidthCTests = []struct { in SPS @@ -47,3 +53,64 @@ func TestSubHeightC(t *testing.T) { } } } + +func TestNewRefPicListModification(t *testing.T) { + tests := []struct { + in string + s SliceHeader + p PPS + want RefPicListModification + }{ + { + in: "1" + // u(1) ref_pic_list_modification_flag_l0=true + // First modification for list0 + "1" + // ue(v) modification_of_pic_nums_idc[0][0] = 0 + "010" + // ue(v) abs_diff_pic_num_minus1[0][0] = 1 + + // Second modification for list0 + "010" + // ue(v) modification_of_pic_nums_idc[0][1] = 1 + "011" + // ue(v) abs_diff_pic_num_minus1[0][1] = 2 + + // Third modification for list0 + "011" + // ue(v) modification_of_pic_nums_idc[0][2] = 2 + "010" + // ue(v) long_term_pic_num = 1 + + // Fourth modification does not exist + "00100" + // ue(v) modification_of_pic_nums_idc[0][3] = 3 + + // Padding bits + "00", + + s: SliceHeader{ + SliceType: 3, + }, + + p: PPS{ + NumRefIdxL0DefaultActiveMinus1: 2, + }, + + want: RefPicListModification{ + RefPicListModificationFlag: [2]bool{true, false}, + ModificationOfPicNums: [2][]int{{0, 1, 2, 3}, {0, 0}}, + AbsDiffPicNumMinus1: [2][]int{{1, 2, 0, 0}, {0, 0}}, + LongTermPicNum: [2][]int{{0, 0, 1, 0}, {0, 0}}, + }, + }, + } + + for i, test := range tests { + inBytes, err := binToSlice(test.in) + if err != nil { + t.Fatalf("unexpected error %v for binToSlice in test %d", err, i) + } + + got, err := NewRefPicListModification(bits.NewBitReader(bytes.NewReader(inBytes)), &test.p, &test.s) + if err != nil { + t.Fatalf("unexpected error %v for NewRefPicListModification in test %d", err, i) + } + + if !reflect.DeepEqual(*got, test.want) { + t.Errorf("did not get expected result for test %d\nGot: %v\nWant: %v\n", i, got, test.want) + } + } +} From 34ce81370d8fe327113a8e4dba7fdb1e31872850 Mon Sep 17 00:00:00 2001 From: Saxon Date: Sun, 4 Aug 2019 13:45:28 +0930 Subject: [PATCH 3/9] codec/h264/h264dec: added file headers to slice.go and slice_test.go --- codec/h264/h264dec/slice.go | 9 +++++++++ codec/h264/h264dec/slice_test.go | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index 6930c89c..024ea13b 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -1,3 +1,12 @@ +/* +DESCRIPTION + slice.go provides parsing functionality for slice RBSP. + +AUTHORS + Saxon Nelson-Milton , The Australian Ocean Laboratory (AusOcean) + mrmod +*/ + package h264dec import ( diff --git a/codec/h264/h264dec/slice_test.go b/codec/h264/h264dec/slice_test.go index 59f8314b..b5de6a6a 100644 --- a/codec/h264/h264dec/slice_test.go +++ b/codec/h264/h264dec/slice_test.go @@ -1,3 +1,12 @@ +/* +DESCRIPTION + slice_test.go provides testing for parsing utilities found in slice.go. + +AUTHORS + Saxon Nelson-Milton , The Australian Ocean Laboratory (AusOcean) + Shawn Smith , The Australian Ocean Laboratory (AusOcean) +*/ + package h264dec import ( From b6eb39f4e0962be5b44a703b3cf91ff55dcf686e Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 5 Aug 2019 00:18:15 +0930 Subject: [PATCH 4/9] codec/h264/h264dec: started added TestNewPredWeightTable --- codec/h264/h264dec/slice_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/codec/h264/h264dec/slice_test.go b/codec/h264/h264dec/slice_test.go index b5de6a6a..375092c9 100644 --- a/codec/h264/h264dec/slice_test.go +++ b/codec/h264/h264dec/slice_test.go @@ -123,3 +123,21 @@ func TestNewRefPicListModification(t *testing.T) { } } } + +func TestNewPredWeightTable(t *testing.T){ + tests := []struct{ + in string + s SliceHeader + want PredWeightTable + }{ + { + in: "011" + // ue(v) luma_log2_weight_denom = 2 + "00100" + // ue(v) chroma_log2_weigght_denom = 3 + + "1" + // u(1) luma_weight_l0_flag = true + "011" + // se(v) luma_weight_l0[0] = -1 + "010" + // se(v) luma_offset_l0[0] = 1 + "1" + // u(1) chroma_weight_l0_flag = true + }, + } +} From c2ac8cff24a1b3631b6b4b39d0a710d34a46d06e Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 5 Aug 2019 01:17:19 +0930 Subject: [PATCH 5/9] codec/h264/h264dec: added TestNewPredWeightTable --- codec/h264/h264dec/helpers.go | 4 +- codec/h264/h264dec/slice.go | 35 ++++----- codec/h264/h264dec/slice_test.go | 123 +++++++++++++++++++++++++++---- 3 files changed, 129 insertions(+), 33 deletions(-) diff --git a/codec/h264/h264dec/helpers.go b/codec/h264/h264dec/helpers.go index 22e9a5eb..947d3895 100644 --- a/codec/h264/h264dec/helpers.go +++ b/codec/h264/h264dec/helpers.go @@ -19,7 +19,7 @@ func binToSlice(s string) ([]byte, error) { bytes []byte ) - for _, c := range s { + for i, c := range s { switch c { case ' ': continue @@ -31,7 +31,7 @@ func binToSlice(s string) ([]byte, error) { } a >>= 1 - if a == 0 { + if a == 0 || i == (len(s)-1) { bytes = append(bytes, cur) cur = 0 a = 0x80 diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index 024ea13b..946a90d9 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -30,6 +30,8 @@ type VideoStream struct { SPS *SPS PPS *PPS Slices []*SliceContext + + ChromaArrayType int } type SliceContext struct { *NALUnit @@ -121,7 +123,6 @@ func NewRefPicListModification(br *bits.BitReader, p *PPS, s *SliceHeader) (*Ref type PredWeightTable struct { LumaLog2WeightDenom int ChromaLog2WeightDenom int - ChromaArrayType int LumaWeightL0Flag bool LumaWeightL0 []int LumaOffsetL0 []int @@ -139,7 +140,7 @@ type PredWeightTable struct { // NewPredWeightTable parses elements of a pred_weight_table following the // syntax structure defined in section 7.3.3.2, and returns as a new // PredWeightTable. -func NewPredWeightTable(br *bits.BitReader, h *SliceHeader) (*PredWeightTable, error) { +func NewPredWeightTable(br *bits.BitReader, h *SliceHeader, chromaArrayType int) (*PredWeightTable, error) { p := &PredWeightTable{} var err error @@ -148,7 +149,7 @@ func NewPredWeightTable(br *bits.BitReader, h *SliceHeader) (*PredWeightTable, e return nil, errors.Wrap(err, "could not parse LumaLog2WeightDenom") } - if p.ChromaArrayType != 0 { + if chromaArrayType != 0 { p.ChromaLog2WeightDenom, err = readUe(br) if err != nil { return nil, errors.Wrap(err, "could not parse ChromaLog2WeightDenom") @@ -174,7 +175,7 @@ func NewPredWeightTable(br *bits.BitReader, h *SliceHeader) (*PredWeightTable, e } p.LumaOffsetL0 = append(p.LumaOffsetL0, se) } - if p.ChromaArrayType != 0 { + if chromaArrayType != 0 { b, err := br.ReadBits(1) if err != nil { return nil, errors.Wrap(err, "could not read ChromaWeightL0Flag") @@ -221,7 +222,7 @@ func NewPredWeightTable(br *bits.BitReader, h *SliceHeader) (*PredWeightTable, e } p.LumaOffsetL1 = append(p.LumaOffsetL1, se) } - if p.ChromaArrayType != 0 { + if chromaArrayType != 0 { b, err := br.ReadBits(1) if err != nil { return nil, errors.Wrap(err, "could not read ChromaWeightL1Flag") @@ -529,7 +530,7 @@ func NumMbPart(nalUnit *NALUnit, sps *SPS, header *SliceHeader, data *SliceData) return numMbPart } -func MbPred(sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error { +func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error { var cabac *CABAC sliceType := sliceTypeMap[sliceContext.Slice.Header.SliceType] mbPartPredMode, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, 0) @@ -630,7 +631,7 @@ func MbPred(sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error { } } - if sliceContext.Slice.Header.ChromaArrayType == 1 || sliceContext.Slice.Header.ChromaArrayType == 2 { + if chromaArrayType == 1 || chromaArrayType == 2 { if sliceContext.PPS.EntropyCodingMode == 1 { // TODO: ue(v) or ae(v) binarization := NewBinarization( @@ -882,7 +883,7 @@ func MbaffFrameFlag(sps *SPS, header *SliceHeader) int { return 0 } -func NewSliceData(sliceContext *SliceContext, br *bits.BitReader) (*SliceData, error) { +func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader) (*SliceData, error) { var cabac *CABAC var err error sliceContext.Slice.Data = &SliceData{BitReader: br} @@ -1117,7 +1118,7 @@ func NewSliceData(sliceContext *SliceContext, br *bits.BitReader) (*SliceData, e } } // TODO: fix nil argument for. - MbPred(sliceContext, br, nil) + MbPred(chromaArrayType, sliceContext, br, nil) } m, err = MbPartPredMode(sliceContext.Slice.Data, sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType, 0) if err != nil { @@ -1136,7 +1137,7 @@ func NewSliceData(sliceContext *SliceContext, br *bits.BitReader) (*SliceData, e } else { me, _ := readMe( br, - uint(sliceContext.Slice.Header.ChromaArrayType), + uint(chromaArrayType), // TODO: fix this //MbPartPredMode(sliceContext.Slice.Data, sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType, 0))) 0) @@ -1213,10 +1214,10 @@ func NewSliceData(sliceContext *SliceContext, br *bits.BitReader) (*SliceData, e func (c *SliceContext) Update(header *SliceHeader, data *SliceData) { c.Slice = &Slice{Header: header, Data: data} } -func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, showPacket bool) (*SliceContext, error) { +func NewSliceContext(vid *VideoStream, nalUnit *NALUnit, rbsp []byte, showPacket bool) (*SliceContext, error) { var err error - sps := videoStream.SPS - pps := videoStream.PPS + sps := vid.SPS + pps := vid.PPS logger.Printf("debug: %s RBSP %d bytes %d bits == \n", NALUnitType[int(nalUnit.Type)], len(rbsp), len(rbsp)*8) logger.Printf("debug: \t%#v\n", rbsp[0:8]) var idrPic bool @@ -1225,9 +1226,9 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh } header := SliceHeader{} if sps.UseSeparateColorPlane { - header.ChromaArrayType = 0 + vid.ChromaArrayType = 0 } else { - header.ChromaArrayType = sps.ChromaFormat + vid.ChromaArrayType = sps.ChromaFormat } br := bits.NewBitReader(bytes.NewReader(rbsp)) @@ -1350,7 +1351,7 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh } if (pps.WeightedPred && (sliceType == "P" || sliceType == "SP")) || (pps.WeightedBipred == 1 && sliceType == "B") { - header.PredWeightTable, err = NewPredWeightTable(br, &header) + header.PredWeightTable, err = NewPredWeightTable(br, &header, vid.ChromaArrayType) if err != nil { return nil, errors.Wrap(err, "could not parse PredWeightTable") } @@ -1420,7 +1421,7 @@ func NewSliceContext(videoStream *VideoStream, nalUnit *NALUnit, rbsp []byte, sh Header: &header, }, } - sliceContext.Slice.Data, err = NewSliceData(sliceContext, br) + sliceContext.Slice.Data, err = NewSliceData(vid.ChromaArrayType,sliceContext, br) if err != nil { return nil, errors.Wrap(err, "could not create slice data") } diff --git a/codec/h264/h264dec/slice_test.go b/codec/h264/h264dec/slice_test.go index 375092c9..522a9eb0 100644 --- a/codec/h264/h264dec/slice_test.go +++ b/codec/h264/h264dec/slice_test.go @@ -85,10 +85,7 @@ func TestNewRefPicListModification(t *testing.T) { "010" + // ue(v) long_term_pic_num = 1 // Fourth modification does not exist - "00100" + // ue(v) modification_of_pic_nums_idc[0][3] = 3 - - // Padding bits - "00", + "00100", // ue(v) modification_of_pic_nums_idc[0][3] = 3 s: SliceHeader{ SliceType: 3, @@ -124,20 +121,118 @@ func TestNewRefPicListModification(t *testing.T) { } } -func TestNewPredWeightTable(t *testing.T){ - tests := []struct{ - in string - s SliceHeader - want PredWeightTable +func TestNewPredWeightTable(t *testing.T) { + tests := []struct { + in string + sliceHeader SliceHeader + chromaArrayType int // ChromaArrayType + want PredWeightTable }{ { in: "011" + // ue(v) luma_log2_weight_denom = 2 - "00100" + // ue(v) chroma_log2_weigght_denom = 3 + "00100" + // ue(v) chroma_log2_weigght_denom = 3 - "1" + // u(1) luma_weight_l0_flag = true - "011" + // se(v) luma_weight_l0[0] = -1 - "010" + // se(v) luma_offset_l0[0] = 1 - "1" + // u(1) chroma_weight_l0_flag = true + // list0 + // i = 0 + "1" + // u(1) luma_weight_l0_flag = true + "011" + // se(v) luma_weight_l0[0] = -1 + "010" + // se(v) luma_offset_l0[0] = 1 + "1" + // u(1) chroma_weight_l0_flag = true + + // i = 0, j = 0 + "010" + // se(v) chroma_weight_l0[0][0] = 1 + "010" + // se(v) chroma_offset_l0[0][0] = 1 + + // i = 0, j = 1 + "010" + // se(v) chroma_weight_l0[0][1] = 1 + "010" + // se(v) chroma_offset_l0[0][1] = 1 + + // i = 1 + "1" + // u(1) luma_weight_l0_flag = true + "011" + // se(v) luma_weight_l0[1] = -1 + "00100" + // se(v) luma_offset_l0[1] = 2 + "1" + // u(1) chroma_weight_l0_flag = true + + // i = 1, j = 0 + "011" + // se(v) chroma_weight_l0[1][0] = -1 + "00101" + // se(v) chroma_offset_l0[1][0] = -2 + + // i = 1, j = 1 + "011" + // se(v) chroma_weight_l0[1][1] = -1 + "011" + // se(v) chroma_offset_l0[1][1] = -1 + + // list1 + // i = 0 + "1" + // u(1) luma_weight_l1_flag = true + "011" + // se(v) luma_weight_l1[0] = -1 + "010" + // se(v) luma_offset_l1[0] = 1 + "1" + // u(1) chroma_weight_l1_flag = true + + // i = 0, j = 0 + "010" + // se(v) chroma_weight_l1[0][0] = 1 + "010" + // se(v) chroma_offset_l1[0][0] = 1 + + // i = 0, j = 1 + "010" + // se(v) chroma_weight_l1[0][1] = 1 + "010" + // se(v) chroma_offset_l1[0][1] = 1 + + // i = 1 + "1" + // u(1) luma_weight_l1_flag = true + "011" + // se(v) luma_weight_l1[1] = -1 + "00100" + // se(v) luma_offset_l1[1] = 2 + "1" + // u(1) chroma_weight_l1_flag = true + + // i = 1, j = 0 + "011" + // se(v) chroma_weight_l0[1][0] = -1 + "00101" + // se(v) chroma_offset_l0[1][0] = -2 + + // i = 1, j = 1 + "011" + // se(v) chroma_weight_l0[1][1] = -1 + "011", // se(v) chroma_offset_l0[1][1] = -1 + + sliceHeader: SliceHeader{ + NumRefIdxL0ActiveMinus1: 1, + NumRefIdxL1ActiveMinus1: 1, + SliceType: 1, + }, + + chromaArrayType: 1, + + want: PredWeightTable{ + LumaLog2WeightDenom: 2, + ChromaLog2WeightDenom: 3, + + LumaWeightL0Flag: true, + LumaWeightL0: []int{-1, -1}, + LumaOffsetL0: []int{1, 2}, + ChromaWeightL0Flag: true, + ChromaWeightL0: [][]int{{1, 1}, {-1, -1}}, + ChromaOffsetL0: [][]int{{1, 1}, {-2, -1}}, + + LumaWeightL1Flag: true, + LumaWeightL1: []int{-1, -1}, + LumaOffsetL1: []int{1, 2}, + ChromaWeightL1Flag: true, + ChromaWeightL1: [][]int{{1, 1}, {-1, -1}}, + ChromaOffsetL1: [][]int{{1, 1}, {-2, -1}}, + }, }, } + + for i, test := range tests { + inBytes, err := binToSlice(test.in) + if err != nil { + t.Fatalf("unexpected error %v for binToSlice in test %d", err, i) + } + + got, err := NewPredWeightTable(bits.NewBitReader(bytes.NewReader(inBytes)), + &test.sliceHeader, test.chromaArrayType) + if err != nil { + t.Fatalf("unexpected error %v for NewPredWeightTable in test %d", err, i) + } + + if !reflect.DeepEqual(*got, test.want) { + t.Errorf("did not get expected result for test %d\nGot: %v\nWant: %v\n", i, got, test.want) + } + } } From 95a5ce0ac0835180dfef045cc756c3ee2e6e575c Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 5 Aug 2019 10:40:20 +0930 Subject: [PATCH 6/9] codec/h264/h264dec: wrote TestDecRefPicMarking and fixed bugs --- codec/h264/h264dec/slice.go | 41 ++++++++++------ codec/h264/h264dec/slice_test.go | 80 ++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 15 deletions(-) diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index 946a90d9..5f819601 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -258,6 +258,10 @@ type DecRefPicMarking struct { NoOutputOfPriorPicsFlag bool LongTermReferenceFlag bool AdaptiveRefPicMarkingModeFlag bool + elements []drpmElement +} + +type drpmElement struct { MemoryManagementControlOperation int DifferenceOfPicNumsMinus1 int LongTermPicNum int @@ -268,7 +272,7 @@ type DecRefPicMarking struct { // NewDecRefPicMarking parses elements of a dec_ref_pic_marking following the // syntax structure defined in section 7.3.3.3, and returns as a new // DecRefPicMarking. -func NewDecRefPicMarking(br *bits.BitReader, idrPic bool, h *SliceHeader) (*DecRefPicMarking, error) { +func NewDecRefPicMarking(br *bits.BitReader, idrPic bool) (*DecRefPicMarking, error) { d := &DecRefPicMarking{} if idrPic { b, err := br.ReadBits(1) @@ -290,35 +294,42 @@ func NewDecRefPicMarking(br *bits.BitReader, idrPic bool, h *SliceHeader) (*DecR d.AdaptiveRefPicMarkingModeFlag = b == 1 if d.AdaptiveRefPicMarkingModeFlag { - d.MemoryManagementControlOperation, err = readUe(br) - if err != nil { - return nil, errors.Wrap(err, "could not parse MemoryManagementControlOperation") - } - for d.MemoryManagementControlOperation != 0 { - if d.MemoryManagementControlOperation == 1 || d.MemoryManagementControlOperation == 3 { - d.DifferenceOfPicNumsMinus1, err = readUe(br) + for i := 0; ; i++ { + d.elements = append(d.elements,drpmElement{}) + + d.elements[i].MemoryManagementControlOperation, err = readUe(br) + if err != nil { + return nil, errors.Wrap(err, "could not parse MemoryManagementControlOperation") + } + + if d.elements[i].MemoryManagementControlOperation == 1 || d.elements[i].MemoryManagementControlOperation == 3 { + d.elements[i].DifferenceOfPicNumsMinus1, err = readUe(br) if err != nil { return nil, errors.Wrap(err, "could not parse MemoryManagementControlOperation") } } - if d.MemoryManagementControlOperation == 2 { - d.LongTermPicNum, err = readUe(br) + if d.elements[i].MemoryManagementControlOperation == 2 { + d.elements[i].LongTermPicNum, err = readUe(br) if err != nil { return nil, errors.Wrap(err, "could not parse LongTermPicNum") } } - if d.MemoryManagementControlOperation == 3 || d.MemoryManagementControlOperation == 6 { - d.LongTermFrameIdx, err = readUe(br) + if d.elements[i].MemoryManagementControlOperation == 3 || d.elements[i].MemoryManagementControlOperation == 6 { + d.elements[i].LongTermFrameIdx, err = readUe(br) if err != nil { return nil, errors.Wrap(err, "could not parse LongTermFrameIdx") } } - if d.MemoryManagementControlOperation == 4 { - d.MaxLongTermFrameIdxPlus1, err = readUe(br) + if d.elements[i].MemoryManagementControlOperation == 4 { + d.elements[i].MaxLongTermFrameIdxPlus1, err = readUe(br) if err != nil { return nil, errors.Wrap(err, "could not parse MaxLongTermFrameIdxPlus1") } } + + if d.elements[i].MemoryManagementControlOperation == 0 { + break + } } } } @@ -1358,7 +1369,7 @@ func NewSliceContext(vid *VideoStream, nalUnit *NALUnit, rbsp []byte, showPacket } if nalUnit.RefIdc != 0 { // devRefPicMarking() - header.DecRefPicMarking, err = NewDecRefPicMarking(br, idrPic, &header) + header.DecRefPicMarking, err = NewDecRefPicMarking(br, idrPic) if err != nil { return nil, errors.Wrap(err, "could not parse DecRefPicMarking") } diff --git a/codec/h264/h264dec/slice_test.go b/codec/h264/h264dec/slice_test.go index 522a9eb0..f0914a4c 100644 --- a/codec/h264/h264dec/slice_test.go +++ b/codec/h264/h264dec/slice_test.go @@ -236,3 +236,83 @@ func TestNewPredWeightTable(t *testing.T) { } } } + +func TestDecRefPicMarking(t *testing.T) { + tests := []struct { + in string + idrPic bool + want DecRefPicMarking + }{ + { + in: "0" + // u(1) no_output_of_prior_pics_flag = false + "1", // u(1) long_term_reference_flag = true + idrPic: true, + want: DecRefPicMarking{ + NoOutputOfPriorPicsFlag: false, + LongTermReferenceFlag: true, + }, + }, + { + in: "1" + // u(1) adaptive_ref_pic_marking_mode_flag = true + + "010" + // ue(v) memory_management_control_operation = 1 + "011" + // ue(v) difference_of_pic_nums_minus1 = 2 + + "00100" + // ue(v) memory_management_control_operation = 3 + "1" + // ue(v) difference_of_pic_nums_minus1 = 0 + "011" + // ue(v) long_term_frame_idx = 2 + + "011" + // ue(v) memory_management_control_operation = 2 + "00100" + // ue(v) long_term_pic_num = 3 + + "00101" + // ue(v) memory_management_control_operation = 4 + "010" + // ue(v) max_long_term_frame_idx_plus1 = 1 + + "1", // ue(v) memory_management_control_operation = 0 + + idrPic: false, + + want: DecRefPicMarking{ + AdaptiveRefPicMarkingModeFlag: true, + elements: []drpmElement{ + { + MemoryManagementControlOperation: 1, + DifferenceOfPicNumsMinus1: 2, + }, + { + MemoryManagementControlOperation: 3, + DifferenceOfPicNumsMinus1: 0, + LongTermFrameIdx: 2, + }, + { + MemoryManagementControlOperation: 2, + LongTermPicNum: 3, + }, + { + MemoryManagementControlOperation: 4, + MaxLongTermFrameIdxPlus1: 1, + }, + { + MemoryManagementControlOperation: 0, + }, + }, + }, + }, + } + + for i, test := range tests { + inBytes, err := binToSlice(test.in) + if err != nil { + t.Fatalf("unexpected error %v for binToSlice in test %d", err, i) + } + + got, err := NewDecRefPicMarking(bits.NewBitReader(bytes.NewReader(inBytes)), test.idrPic) + if err != nil { + t.Fatalf("unexpected error %v for NewPredWeightTable in test %d", err, i) + } + + if !reflect.DeepEqual(*got, test.want) { + t.Errorf("did not get expected result for test %d\nGot: %v\nWant: %v\n", i, got, test.want) + } + } +} From 27d8d0992cde5fd7f117f33f9041d5120d2b7053 Mon Sep 17 00:00:00 2001 From: Saxon Date: Tue, 20 Aug 2019 11:56:42 +0930 Subject: [PATCH 7/9] codec/h264/h264dec/slice.go: made corrections to file header --- codec/h264/h264dec/slice.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index a46360c9..3b7c4a57 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -1,10 +1,10 @@ /* DESCRIPTION - slice.go provides parsing functionality for slice RBSP. + slice.go provides parsing functionality for slice raw byte sequence data. AUTHORS Saxon Nelson-Milton , The Australian Ocean Laboratory (AusOcean) - mrmod + Bruce McMoran */ package h264dec From bdcd3408021979c50e4e7011a3aea98bf3b01457 Mon Sep 17 00:00:00 2001 From: Saxon Date: Tue, 20 Aug 2019 12:02:39 +0930 Subject: [PATCH 8/9] codec/h264/h264dec/slice_test.go: removed redundant comment --- codec/h264/h264dec/slice_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codec/h264/h264dec/slice_test.go b/codec/h264/h264dec/slice_test.go index 55e249ea..3f0282b0 100644 --- a/codec/h264/h264dec/slice_test.go +++ b/codec/h264/h264dec/slice_test.go @@ -125,7 +125,7 @@ func TestNewPredWeightTable(t *testing.T) { tests := []struct { in string sliceHeader SliceHeader - chromaArrayType int // ChromaArrayType + chromaArrayType int want PredWeightTable }{ { From 0f35786d0693dc114e4796034aec0c13283b13a8 Mon Sep 17 00:00:00 2001 From: Saxon Date: Tue, 20 Aug 2019 12:06:11 +0930 Subject: [PATCH 9/9] codec/h264/h264dec/slice_test.go: added license information to file header --- codec/h264/h264dec/slice_test.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/codec/h264/h264dec/slice_test.go b/codec/h264/h264dec/slice_test.go index 3f0282b0..e9bdee9f 100644 --- a/codec/h264/h264dec/slice_test.go +++ b/codec/h264/h264dec/slice_test.go @@ -1,10 +1,26 @@ /* DESCRIPTION - slice_test.go provides testing for parsing utilities found in slice.go. + slice_test.go provides testing for parsing functionality found in slice.go. AUTHORS - Saxon Nelson-Milton , The Australian Ocean Laboratory (AusOcean) - Shawn Smith , The Australian Ocean Laboratory (AusOcean) + Saxon Nelson-Milton + Shawn Smith + +LICENSE + Copyright (C) 2019 the Australian Ocean Lab (AusOcean). + + It is free software: you can redistribute it and/or modify them + under the terms of the GNU General Public License as published by the + Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + It is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + in gpl.txt. If not, see http://www.gnu.org/licenses. */ package h264dec