From ce803ba4883c7f7b668c363ec9aacc072f010579 Mon Sep 17 00:00:00 2001 From: Saxon Date: Fri, 6 Sep 2019 17:45:23 +0930 Subject: [PATCH 01/18] codec/h264/h264dec: add function for parsing level information using process in section 9.2.2 of specifications --- codec/h264/h264dec/cavlc.go | 91 +++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/codec/h264/h264dec/cavlc.go b/codec/h264/h264dec/cavlc.go index c477a490..0dcbc64b 100644 --- a/codec/h264/h264dec/cavlc.go +++ b/codec/h264/h264dec/cavlc.go @@ -26,6 +26,7 @@ LICENSE package h264dec import ( + "errors" "fmt" "bitbucket.org/ausocean/av/codec/h264/h264dec/bits" @@ -44,3 +45,93 @@ func parseLevelPrefix(br *bits.BitReader) (int, error) { } return zeros, nil } + +// parseLevelInformation parses level information and returns the resultant +// levelVal list using the process defined by section 9.2.2 in the specifications. +func parseLevelInformation(br *bits.BitReader, totalCoeff, trailingOnes int) ([]int, error) { + var levelVal []int + var i int + if trailingOnes != 0 { + for ; i < trailingOnes; i++ { + b, err := br.ReadBits(1) + if err != nil { + return nil, fmt.Errorf("could not read trailing_ones_sign_flag, failed with error: %v", err) + } + if b == 0 { + levelVal = append(levelVal, 1) + continue + } + levelVal = append(levelVal, -1) + } + } + + var suffixLen int + switch { + case totalCoeff > 10 && trailingOnes < 3: + suffixLen = 1 + case totalCoeff <= 10 || trailingOnes == 3: + suffixLen = 0 + default: + return nil, errors.New("invalid TotalCoeff and TrailingOnes combination") + } + + if totalCoeff-trailingOnes != 0 { + for j := 0; j < totalCoeff-trailingOnes; j++ { + levelPrefix, err := parseLevelPrefix(br) + if err != nil { + return nil, fmt.Errorf("could not parse level prefix, failed with error: %v", err) + } + + var levelSuffixSize int + switch { + case levelPrefix == 14 && suffixLen == 0: + levelSuffixSize = 4 + case levelPrefix >= 15: + levelSuffixSize = levelPrefix - 3 + default: + levelSuffixSize = suffixLen + } + + var levelSuffix int + if levelSuffixSize > 0 { + b, err := br.ReadBits(levelSuffixSize) + if err != nil { + return nil, fmt.Errorf("could not parse levelSuffix, failed with error: %v", err) + } + levelSuffix = int(b) + } else { + levelSuffix = 0 + } + + levelCode := (mini(15, levelPrefix) << uint(suffixLen)) + levelSuffix + + if levelPrefix >= 15 && suffixLen == 0 { + levelCode += 15 + } + + if levelPrefix >= 16 { + levelCode += (1 << uint(levelPrefix-3)) - 4096 + } + + if i == trailingOnes && trailingOnes < 3 { + levelCode += 2 + } + + if levelCode%2 == 0 { + levelVal = append(levelVal, (levelCode+2)>>1) + } else { + levelVal = append(levelVal, (-levelCode-1)>>1) + } + + if suffixLen == 0 { + suffixLen = 1 + } + + if absi(levelVal[i]) > (3< Date: Sun, 8 Sep 2019 13:31:10 +0930 Subject: [PATCH 02/18] codec/h264/h264dec/cavlc.go: removed redundant if checks in parseLevelInformation --- codec/h264/h264dec/cavlc.go | 130 +++++++++++++++++------------------- 1 file changed, 63 insertions(+), 67 deletions(-) diff --git a/codec/h264/h264dec/cavlc.go b/codec/h264/h264dec/cavlc.go index 0dcbc64b..820ec67c 100644 --- a/codec/h264/h264dec/cavlc.go +++ b/codec/h264/h264dec/cavlc.go @@ -51,18 +51,16 @@ func parseLevelPrefix(br *bits.BitReader) (int, error) { func parseLevelInformation(br *bits.BitReader, totalCoeff, trailingOnes int) ([]int, error) { var levelVal []int var i int - if trailingOnes != 0 { - for ; i < trailingOnes; i++ { - b, err := br.ReadBits(1) - if err != nil { - return nil, fmt.Errorf("could not read trailing_ones_sign_flag, failed with error: %v", err) - } - if b == 0 { - levelVal = append(levelVal, 1) - continue - } - levelVal = append(levelVal, -1) + for ; i < trailingOnes; i++ { + b, err := br.ReadBits(1) + if err != nil { + return nil, fmt.Errorf("could not read trailing_ones_sign_flag, failed with error: %v", err) } + if b == 0 { + levelVal = append(levelVal, 1) + continue + } + levelVal = append(levelVal, -1) } var suffixLen int @@ -75,63 +73,61 @@ func parseLevelInformation(br *bits.BitReader, totalCoeff, trailingOnes int) ([] return nil, errors.New("invalid TotalCoeff and TrailingOnes combination") } - if totalCoeff-trailingOnes != 0 { - for j := 0; j < totalCoeff-trailingOnes; j++ { - levelPrefix, err := parseLevelPrefix(br) - if err != nil { - return nil, fmt.Errorf("could not parse level prefix, failed with error: %v", err) - } - - var levelSuffixSize int - switch { - case levelPrefix == 14 && suffixLen == 0: - levelSuffixSize = 4 - case levelPrefix >= 15: - levelSuffixSize = levelPrefix - 3 - default: - levelSuffixSize = suffixLen - } - - var levelSuffix int - if levelSuffixSize > 0 { - b, err := br.ReadBits(levelSuffixSize) - if err != nil { - return nil, fmt.Errorf("could not parse levelSuffix, failed with error: %v", err) - } - levelSuffix = int(b) - } else { - levelSuffix = 0 - } - - levelCode := (mini(15, levelPrefix) << uint(suffixLen)) + levelSuffix - - if levelPrefix >= 15 && suffixLen == 0 { - levelCode += 15 - } - - if levelPrefix >= 16 { - levelCode += (1 << uint(levelPrefix-3)) - 4096 - } - - if i == trailingOnes && trailingOnes < 3 { - levelCode += 2 - } - - if levelCode%2 == 0 { - levelVal = append(levelVal, (levelCode+2)>>1) - } else { - levelVal = append(levelVal, (-levelCode-1)>>1) - } - - if suffixLen == 0 { - suffixLen = 1 - } - - if absi(levelVal[i]) > (3<= 15: + levelSuffixSize = levelPrefix - 3 + default: + levelSuffixSize = suffixLen + } + + var levelSuffix int + if levelSuffixSize > 0 { + b, err := br.ReadBits(levelSuffixSize) + if err != nil { + return nil, fmt.Errorf("could not parse levelSuffix, failed with error: %v", err) + } + levelSuffix = int(b) + } else { + levelSuffix = 0 + } + + levelCode := (mini(15, levelPrefix) << uint(suffixLen)) + levelSuffix + + if levelPrefix >= 15 && suffixLen == 0 { + levelCode += 15 + } + + if levelPrefix >= 16 { + levelCode += (1 << uint(levelPrefix-3)) - 4096 + } + + if i == trailingOnes && trailingOnes < 3 { + levelCode += 2 + } + + if levelCode%2 == 0 { + levelVal = append(levelVal, (levelCode+2)>>1) + } else { + levelVal = append(levelVal, (-levelCode-1)>>1) + } + + if suffixLen == 0 { + suffixLen = 1 + } + + if absi(levelVal[i]) > (3< Date: Sun, 8 Sep 2019 13:52:58 +0930 Subject: [PATCH 03/18] codec/h264/h2646dec: added decode.go file to hold slice decoding functionality --- codec/h264/h264dec/decode.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 codec/h264/h264dec/decode.go diff --git a/codec/h264/h264dec/decode.go b/codec/h264/h264dec/decode.go new file mode 100644 index 00000000..22cfc181 --- /dev/null +++ b/codec/h264/h264dec/decode.go @@ -0,0 +1,25 @@ +/* +DESCRIPTION + decode.go provides slice decoding functionality. + +AUTHORS + Saxon A. Nelson-Milton + +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 From 46e7f9d303e8f8393a6b15be717be1959bcee0f9 Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 9 Sep 2019 09:11:50 +0930 Subject: [PATCH 04/18] codec/h264/h264dec/cavlc.go: simplified some logic regarding appending of values onto levelVal based on trailing_ones_sign_flag --- codec/h264/h264dec/cavlc.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/codec/h264/h264dec/cavlc.go b/codec/h264/h264dec/cavlc.go index 820ec67c..e1932548 100644 --- a/codec/h264/h264dec/cavlc.go +++ b/codec/h264/h264dec/cavlc.go @@ -56,11 +56,7 @@ func parseLevelInformation(br *bits.BitReader, totalCoeff, trailingOnes int) ([] if err != nil { return nil, fmt.Errorf("could not read trailing_ones_sign_flag, failed with error: %v", err) } - if b == 0 { - levelVal = append(levelVal, 1) - continue - } - levelVal = append(levelVal, -1) + levelVal = append(levelVal, 1-int(b)*2) } var suffixLen int From fbb98095a0a572e8c6de37fcb14f330e53785a2b Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 9 Sep 2019 11:08:48 +0930 Subject: [PATCH 05/18] codec/h264/h264dec: embedded SliceHeader and SliceData into Slice type, and embedded SPS and PPS into VideoStream type --- codec/h264/h264dec/cabac.go | 10 +- codec/h264/h264dec/slice.go | 315 ++++++++++++++++++------------------ 2 files changed, 162 insertions(+), 163 deletions(-) diff --git a/codec/h264/h264dec/cabac.go b/codec/h264/h264dec/cabac.go index 7b28414e..25d3bec9 100644 --- a/codec/h264/h264dec/cabac.go +++ b/codec/h264/h264dec/cabac.go @@ -171,7 +171,7 @@ type CABAC struct { } // table 9-1 -func initCabac(binarization *Binarization, context *SliceContext) *CABAC { +func initCabac(binarization *Binarization, vid *VideoStream, ctx *SliceContext) *CABAC { var valMPS, pStateIdx int // TODO: When to use prefix, when to use suffix? ctxIdx := CtxIdx( @@ -180,7 +180,7 @@ func initCabac(binarization *Binarization, context *SliceContext) *CABAC { binarization.CtxIdxOffset.Prefix) mn := MNVars[ctxIdx] - preCtxState := PreCtxState(mn[0].M, mn[0].N, SliceQPy(context.PPS, context.Header)) + preCtxState := PreCtxState(mn[0].M, mn[0].N, SliceQPy(vid.PPS, ctx.SliceHeader)) if preCtxState <= 63 { pStateIdx = 63 - preCtxState valMPS = 0 @@ -195,7 +195,7 @@ func initCabac(binarization *Binarization, context *SliceContext) *CABAC { return &CABAC{ PStateIdx: pStateIdx, ValMPS: valMPS, - Context: context, + Context: ctx, } } @@ -457,7 +457,7 @@ func NewArithmeticDecoding(context *SliceContext, binarization *Binarization, ct if binarization.UseDecodeBypass == 1 { // TODO: 9.3.3.2.3 : DecodeBypass() var err error - codIOffset, a.BinVal, err = a.DecodeBypass(context.Slice.Data, codIRange, codIOffset) + codIOffset, a.BinVal, err = a.DecodeBypass(context.SliceData, codIRange, codIOffset) if err != nil { return ArithmeticDecoding{}, errors.Wrap(err, "error from DecodeBypass getting codIOffset and BinVal") } @@ -539,7 +539,7 @@ type ArithmeticDecoding struct { // returns: binVal, updated codIRange, updated codIOffset func (a ArithmeticDecoding) BinaryDecision(ctxIdx, codIRange, codIOffset int) (int, int, int, error) { var binVal int - cabac := initCabac(a.Binarization, a.Context) + cabac := initCabac(a.Binarization, nil, a.Context) // Derivce codIRangeLPS qCodIRangeIdx := (codIRange >> 6) & 3 pStateIdx := cabac.PStateIdx diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index 05fe33ea..4952cfd9 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -36,21 +36,21 @@ const ( ) type VideoStream struct { - SPS *SPS - PPS *PPS + *SPS + *PPS Slices []*SliceContext ChromaArrayType int } + type SliceContext struct { *NALUnit - *SPS - *PPS *Slice } + type Slice struct { - Header *SliceHeader - Data *SliceData + *SliceHeader + *SliceData } // RefPicListModification provides elements of a ref_pic_list_modification syntax @@ -526,12 +526,12 @@ func NumMbPart(nalUnit *NALUnit, sps *SPS, header *SliceHeader, data *SliceData) return numMbPart } -func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error { +func MbPred(chromaArrayType int, vid *VideoStream, sliceContext *SliceContext, br *bits.BitReader, rbsp []byte) error { var cabac *CABAC r := newFieldReader(br) - sliceType := sliceTypeMap[sliceContext.Slice.Header.SliceType] - mbPartPredMode, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, 0) + sliceType := sliceTypeMap[sliceContext.Slice.SliceHeader.SliceType] + mbPartPredMode, err := MbPartPredMode(sliceContext.Slice.SliceData, sliceType, sliceContext.Slice.SliceData.MbType, 0) if err != nil { return errors.Wrap(err, "could not get mbPartPredMode") } @@ -539,14 +539,15 @@ func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, if mbPartPredMode == intra4x4 { for luma4x4BlkIdx := 0; luma4x4BlkIdx < 16; luma4x4BlkIdx++ { var v int - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: 1 bit or ae(v) binarization := NewBinarization( "PrevIntra4x4PredModeFlag", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) - cabac = initCabac(binarization, sliceContext) + // TODO: fix videostream should be nil. + cabac = initCabac(binarization, nil, sliceContext) _ = cabac logger.Printf("TODO: ae for PevIntra4x4PredModeFlag[%d]\n", luma4x4BlkIdx) } else { @@ -556,15 +557,15 @@ func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, } v = int(b) } - sliceContext.Slice.Data.PrevIntra4x4PredModeFlag = append( - sliceContext.Slice.Data.PrevIntra4x4PredModeFlag, + sliceContext.Slice.SliceData.PrevIntra4x4PredModeFlag = append( + sliceContext.Slice.SliceData.PrevIntra4x4PredModeFlag, v) - if sliceContext.Slice.Data.PrevIntra4x4PredModeFlag[luma4x4BlkIdx] == 0 { - if sliceContext.PPS.EntropyCodingMode == 1 { + if sliceContext.Slice.SliceData.PrevIntra4x4PredModeFlag[luma4x4BlkIdx] == 0 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: 3 bits or ae(v) binarization := NewBinarization( "RemIntra4x4PredMode", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) logger.Printf("TODO: ae for RemIntra4x4PredMode[%d]\n", luma4x4BlkIdx) @@ -575,22 +576,22 @@ func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, } v = int(b) } - if len(sliceContext.Slice.Data.RemIntra4x4PredMode) < luma4x4BlkIdx { - sliceContext.Slice.Data.RemIntra4x4PredMode = append( - sliceContext.Slice.Data.RemIntra4x4PredMode, - make([]int, luma4x4BlkIdx-len(sliceContext.Slice.Data.RemIntra4x4PredMode)+1)...) + if len(sliceContext.Slice.SliceData.RemIntra4x4PredMode) < luma4x4BlkIdx { + sliceContext.Slice.SliceData.RemIntra4x4PredMode = append( + sliceContext.Slice.SliceData.RemIntra4x4PredMode, + make([]int, luma4x4BlkIdx-len(sliceContext.Slice.SliceData.RemIntra4x4PredMode)+1)...) } - sliceContext.Slice.Data.RemIntra4x4PredMode[luma4x4BlkIdx] = v + sliceContext.Slice.SliceData.RemIntra4x4PredMode[luma4x4BlkIdx] = v } } } if mbPartPredMode == intra8x8 { for luma8x8BlkIdx := 0; luma8x8BlkIdx < 4; luma8x8BlkIdx++ { - sliceContext.Update(sliceContext.Slice.Header, sliceContext.Slice.Data) + sliceContext.Update(sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData) var v int - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: 1 bit or ae(v) - binarization := NewBinarization("PrevIntra8x8PredModeFlag", sliceContext.Slice.Data) + binarization := NewBinarization("PrevIntra8x8PredModeFlag", sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) logger.Printf("TODO: ae for PrevIntra8x8PredModeFlag[%d]\n", luma8x8BlkIdx) @@ -601,14 +602,14 @@ func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, } v = int(b) } - sliceContext.Slice.Data.PrevIntra8x8PredModeFlag = append( - sliceContext.Slice.Data.PrevIntra8x8PredModeFlag, v) - if sliceContext.Slice.Data.PrevIntra8x8PredModeFlag[luma8x8BlkIdx] == 0 { - if sliceContext.PPS.EntropyCodingMode == 1 { + sliceContext.Slice.SliceData.PrevIntra8x8PredModeFlag = append( + sliceContext.Slice.SliceData.PrevIntra8x8PredModeFlag, v) + if sliceContext.Slice.SliceData.PrevIntra8x8PredModeFlag[luma8x8BlkIdx] == 0 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: 3 bits or ae(v) binarization := NewBinarization( "RemIntra8x8PredMode", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) logger.Printf("TODO: ae for RemIntra8x8PredMode[%d]\n", luma8x8BlkIdx) @@ -619,138 +620,138 @@ func MbPred(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader, } v = int(b) } - if len(sliceContext.Slice.Data.RemIntra8x8PredMode) < luma8x8BlkIdx { - sliceContext.Slice.Data.RemIntra8x8PredMode = append( - sliceContext.Slice.Data.RemIntra8x8PredMode, - make([]int, luma8x8BlkIdx-len(sliceContext.Slice.Data.RemIntra8x8PredMode)+1)...) + if len(sliceContext.Slice.SliceData.RemIntra8x8PredMode) < luma8x8BlkIdx { + sliceContext.Slice.SliceData.RemIntra8x8PredMode = append( + sliceContext.Slice.SliceData.RemIntra8x8PredMode, + make([]int, luma8x8BlkIdx-len(sliceContext.Slice.SliceData.RemIntra8x8PredMode)+1)...) } - sliceContext.Slice.Data.RemIntra8x8PredMode[luma8x8BlkIdx] = v + sliceContext.Slice.SliceData.RemIntra8x8PredMode[luma8x8BlkIdx] = v } } } if chromaArrayType == 1 || chromaArrayType == 2 { - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: ue(v) or ae(v) binarization := NewBinarization( "IntraChromaPredMode", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) logger.Printf("TODO: ae for IntraChromaPredMode\n") } else { - sliceContext.Slice.Data.IntraChromaPredMode = int(r.readUe()) + sliceContext.Slice.SliceData.IntraChromaPredMode = int(r.readUe()) } } } else if mbPartPredMode != direct { - for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ { - sliceContext.Update(sliceContext.Slice.Header, sliceContext.Slice.Data) - m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx) + for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, vid.SPS, sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData); mbPartIdx++ { + sliceContext.Update(sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData) + m, err := MbPartPredMode(sliceContext.Slice.SliceData, sliceType, sliceContext.Slice.SliceData.MbType, mbPartIdx) if err != nil { return errors.Wrap(err, fmt.Sprintf("could not get mbPartPredMode for loop 1 mbPartIdx: %d", mbPartIdx)) } - if (sliceContext.Slice.Header.NumRefIdxL0ActiveMinus1 > 0 || sliceContext.Slice.Data.MbFieldDecodingFlag != sliceContext.Slice.Header.FieldPic) && m != predL1 { + if (sliceContext.Slice.SliceHeader.NumRefIdxL0ActiveMinus1 > 0 || sliceContext.Slice.SliceData.MbFieldDecodingFlag != sliceContext.Slice.SliceHeader.FieldPic) && m != predL1 { logger.Printf("\tTODO: refIdxL0[%d] te or ae(v)\n", mbPartIdx) - if len(sliceContext.Slice.Data.RefIdxL0) < mbPartIdx { - sliceContext.Slice.Data.RefIdxL0 = append( - sliceContext.Slice.Data.RefIdxL0, make([]int, mbPartIdx-len(sliceContext.Slice.Data.RefIdxL0)+1)...) + if len(sliceContext.Slice.SliceData.RefIdxL0) < mbPartIdx { + sliceContext.Slice.SliceData.RefIdxL0 = append( + sliceContext.Slice.SliceData.RefIdxL0, make([]int, mbPartIdx-len(sliceContext.Slice.SliceData.RefIdxL0)+1)...) } - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: te(v) or ae(v) binarization := NewBinarization( "RefIdxL0", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) logger.Printf("TODO: ae for RefIdxL0[%d]\n", mbPartIdx) } else { // TODO: Only one reference picture is used for inter-prediction, // then the value should be 0 - if MbaffFrameFlag(sliceContext.SPS, sliceContext.Slice.Header) == 0 || !sliceContext.Slice.Data.MbFieldDecodingFlag { - sliceContext.Slice.Data.RefIdxL0[mbPartIdx] = int(r.readTe(uint(sliceContext.Slice.Header.NumRefIdxL0ActiveMinus1))) + if MbaffFrameFlag(vid.SPS, sliceContext.Slice.SliceHeader) == 0 || !sliceContext.Slice.SliceData.MbFieldDecodingFlag { + sliceContext.Slice.SliceData.RefIdxL0[mbPartIdx] = int(r.readTe(uint(sliceContext.Slice.SliceHeader.NumRefIdxL0ActiveMinus1))) } else { - rangeMax := 2*sliceContext.Slice.Header.NumRefIdxL0ActiveMinus1 + 1 - sliceContext.Slice.Data.RefIdxL0[mbPartIdx] = int(r.readTe(uint(rangeMax))) + rangeMax := 2*sliceContext.Slice.SliceHeader.NumRefIdxL0ActiveMinus1 + 1 + sliceContext.Slice.SliceData.RefIdxL0[mbPartIdx] = int(r.readTe(uint(rangeMax))) } } } } - for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ { - m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx) + for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, vid.SPS, sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData); mbPartIdx++ { + m, err := MbPartPredMode(sliceContext.Slice.SliceData, sliceType, sliceContext.Slice.SliceData.MbType, mbPartIdx) if err != nil { return errors.Wrap(err, fmt.Sprintf("could not get mbPartPredMode for loop 2 mbPartIdx: %d", mbPartIdx)) } if m != predL1 { for compIdx := 0; compIdx < 2; compIdx++ { - if len(sliceContext.Slice.Data.MvdL0) < mbPartIdx { - sliceContext.Slice.Data.MvdL0 = append( - sliceContext.Slice.Data.MvdL0, - make([][][]int, mbPartIdx-len(sliceContext.Slice.Data.MvdL0)+1)...) + if len(sliceContext.Slice.SliceData.MvdL0) < mbPartIdx { + sliceContext.Slice.SliceData.MvdL0 = append( + sliceContext.Slice.SliceData.MvdL0, + make([][][]int, mbPartIdx-len(sliceContext.Slice.SliceData.MvdL0)+1)...) } - if len(sliceContext.Slice.Data.MvdL0[mbPartIdx][0]) < compIdx { - sliceContext.Slice.Data.MvdL0[mbPartIdx][0] = append( - sliceContext.Slice.Data.MvdL0[mbPartIdx][0], - make([]int, compIdx-len(sliceContext.Slice.Data.MvdL0[mbPartIdx][0])+1)...) + if len(sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0]) < compIdx { + sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0] = append( + sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0], + make([]int, compIdx-len(sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0])+1)...) } - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: se(v) or ae(v) if compIdx == 0 { binarization := NewBinarization( "MvdLnEnd0", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) } else if compIdx == 1 { binarization := NewBinarization( "MvdLnEnd1", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) } logger.Printf("TODO: ae for MvdL0[%d][0][%d]\n", mbPartIdx, compIdx) } else { - sliceContext.Slice.Data.MvdL0[mbPartIdx][0][compIdx], _ = readSe(br) + sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0][compIdx], _ = readSe(br) } } } } - for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data); mbPartIdx++ { - sliceContext.Update(sliceContext.Slice.Header, sliceContext.Slice.Data) - m, err := MbPartPredMode(sliceContext.Slice.Data, sliceType, sliceContext.Slice.Data.MbType, mbPartIdx) + for mbPartIdx := 0; mbPartIdx < NumMbPart(sliceContext.NALUnit, vid.SPS, sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData); mbPartIdx++ { + sliceContext.Update(sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData) + m, err := MbPartPredMode(sliceContext.Slice.SliceData, sliceType, sliceContext.Slice.SliceData.MbType, mbPartIdx) if err != nil { return errors.Wrap(err, fmt.Sprintf("could not get mbPartPredMode for loop 3 mbPartIdx: %d", mbPartIdx)) } if m != predL0 { for compIdx := 0; compIdx < 2; compIdx++ { - if len(sliceContext.Slice.Data.MvdL1) < mbPartIdx { - sliceContext.Slice.Data.MvdL1 = append( - sliceContext.Slice.Data.MvdL1, - make([][][]int, mbPartIdx-len(sliceContext.Slice.Data.MvdL1)+1)...) + if len(sliceContext.Slice.SliceData.MvdL1) < mbPartIdx { + sliceContext.Slice.SliceData.MvdL1 = append( + sliceContext.Slice.SliceData.MvdL1, + make([][][]int, mbPartIdx-len(sliceContext.Slice.SliceData.MvdL1)+1)...) } - if len(sliceContext.Slice.Data.MvdL1[mbPartIdx][0]) < compIdx { - sliceContext.Slice.Data.MvdL1[mbPartIdx][0] = append( - sliceContext.Slice.Data.MvdL0[mbPartIdx][0], - make([]int, compIdx-len(sliceContext.Slice.Data.MvdL1[mbPartIdx][0])+1)...) + if len(sliceContext.Slice.SliceData.MvdL1[mbPartIdx][0]) < compIdx { + sliceContext.Slice.SliceData.MvdL1[mbPartIdx][0] = append( + sliceContext.Slice.SliceData.MvdL0[mbPartIdx][0], + make([]int, compIdx-len(sliceContext.Slice.SliceData.MvdL1[mbPartIdx][0])+1)...) } - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { if compIdx == 0 { binarization := NewBinarization( "MvdLnEnd0", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) } else if compIdx == 1 { binarization := NewBinarization( "MvdLnEnd1", - sliceContext.Slice.Data) + sliceContext.Slice.SliceData) binarization.Decode(sliceContext, br, rbsp) } // TODO: se(v) or ae(v) logger.Printf("TODO: ae for MvdL1[%d][0][%d]\n", mbPartIdx, compIdx) } else { - sliceContext.Slice.Data.MvdL1[mbPartIdx][0][compIdx], _ = readSe(br) + sliceContext.Slice.SliceData.MvdL1[mbPartIdx][0][compIdx], _ = readSe(br) } } } @@ -873,47 +874,47 @@ func MbaffFrameFlag(sps *SPS, header *SliceHeader) int { return 0 } -func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitReader) (*SliceData, error) { +func NewSliceData(chromaArrayType int, vid *VideoStream, sliceContext *SliceContext, br *bits.BitReader) (*SliceData, error) { r := newFieldReader(br) var cabac *CABAC - sliceContext.Slice.Data = &SliceData{BitReader: br} + sliceContext.Slice.SliceData = &SliceData{BitReader: br} // TODO: Why is this being initialized here? // initCabac(sliceContext) - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { for !br.ByteAligned() { b, err := br.ReadBits(1) if err != nil { return nil, errors.Wrap(err, "could not read CabacAlignmentOneBit") } - sliceContext.Slice.Data.CabacAlignmentOneBit = int(b) + sliceContext.Slice.SliceData.CabacAlignmentOneBit = int(b) } } mbaffFrameFlag := 0 - if sliceContext.SPS.MBAdaptiveFrameFieldFlag && !sliceContext.Slice.Header.FieldPic { + if vid.SPS.MBAdaptiveFrameFieldFlag && !sliceContext.Slice.SliceHeader.FieldPic { mbaffFrameFlag = 1 } - currMbAddr := sliceContext.Slice.Header.FirstMbInSlice * (1 * mbaffFrameFlag) + currMbAddr := sliceContext.Slice.SliceHeader.FirstMbInSlice * (1 * mbaffFrameFlag) moreDataFlag := true prevMbSkipped := 0 - sliceContext.Slice.Data.SliceTypeName = sliceTypeMap[sliceContext.Slice.Header.SliceType] - sliceContext.Slice.Data.MbTypeName = MbTypeName(sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType) + sliceContext.Slice.SliceData.SliceTypeName = sliceTypeMap[sliceContext.Slice.SliceHeader.SliceType] + sliceContext.Slice.SliceData.MbTypeName = MbTypeName(sliceContext.Slice.SliceData.SliceTypeName, sliceContext.Slice.SliceData.MbType) logger.Printf("debug: \tSliceData: Processing moreData: %v\n", moreDataFlag) for moreDataFlag { - logger.Printf("debug: \tLooking for more sliceContext.Slice.Data in slice type %s\n", sliceContext.Slice.Data.SliceTypeName) - if sliceContext.Slice.Data.SliceTypeName != "I" && sliceContext.Slice.Data.SliceTypeName != "SI" { + logger.Printf("debug: \tLooking for more sliceContext.Slice.SliceData in slice type %s\n", sliceContext.Slice.SliceData.SliceTypeName) + if sliceContext.Slice.SliceData.SliceTypeName != "I" && sliceContext.Slice.SliceData.SliceTypeName != "SI" { logger.Printf("debug: \tNonI/SI slice, processing moreData\n") - if sliceContext.PPS.EntropyCodingMode == 0 { - sliceContext.Slice.Data.MbSkipRun = int(r.readUe()) + if vid.PPS.EntropyCodingMode == 0 { + sliceContext.Slice.SliceData.MbSkipRun = int(r.readUe()) - if sliceContext.Slice.Data.MbSkipRun > 0 { + if sliceContext.Slice.SliceData.MbSkipRun > 0 { prevMbSkipped = 1 } - for i := 0; i < sliceContext.Slice.Data.MbSkipRun; i++ { + for i := 0; i < sliceContext.Slice.SliceData.MbSkipRun; i++ { // nextMbAddress(currMbAdd - currMbAddr = nextMbAddress(currMbAddr, sliceContext.SPS, sliceContext.PPS, sliceContext.Slice.Header) + currMbAddr = nextMbAddress(currMbAddr, vid.SPS, vid.PPS, sliceContext.Slice.SliceHeader) } - if sliceContext.Slice.Data.MbSkipRun > 0 { + if sliceContext.Slice.SliceData.MbSkipRun > 0 { moreDataFlag = moreRBSPData(br) } } else { @@ -921,16 +922,16 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if err != nil { return nil, errors.Wrap(err, "could not read MbSkipFlag") } - sliceContext.Slice.Data.MbSkipFlag = b == 1 + sliceContext.Slice.SliceData.MbSkipFlag = b == 1 - moreDataFlag = !sliceContext.Slice.Data.MbSkipFlag + moreDataFlag = !sliceContext.Slice.SliceData.MbSkipFlag } } if moreDataFlag { if mbaffFrameFlag == 1 && (currMbAddr%2 == 0 || (currMbAddr%2 == 1 && prevMbSkipped == 1)) { - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: ae implementation - binarization := NewBinarization("MbFieldDecodingFlag", sliceContext.Slice.Data) + binarization := NewBinarization("MbFieldDecodingFlag", sliceContext.Slice.SliceData) // TODO: this should take a BitReader where the nil is. binarization.Decode(sliceContext, br, nil) @@ -940,15 +941,15 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if err != nil { return nil, errors.Wrap(err, "could not read MbFieldDecodingFlag") } - sliceContext.Slice.Data.MbFieldDecodingFlag = b == 1 + sliceContext.Slice.SliceData.MbFieldDecodingFlag = b == 1 } } // BEGIN: macroblockLayer() - if sliceContext.PPS.EntropyCodingMode == 1 { + if vid.PPS.EntropyCodingMode == 1 { // TODO: ae implementation - binarization := NewBinarization("MbType", sliceContext.Slice.Data) - cabac = initCabac(binarization, sliceContext) + binarization := NewBinarization("MbType", sliceContext.Slice.SliceData) + cabac = initCabac(binarization, nil, sliceContext) _ = cabac // TODO: remove bytes parameter from this function. binarization.Decode(sliceContext, br, nil) @@ -964,7 +965,7 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if binarization.UseDecodeBypass == 1 { // DecodeBypass logger.Printf("TODO: decodeBypass is set: 9.3.3.2.3") - codIRange, codIOffset, err := initDecodingEngine(sliceContext.Slice.Data.BitReader) + codIRange, codIOffset, err := initDecodingEngine(sliceContext.Slice.SliceData.BitReader) if err != nil { return nil, errors.Wrap(err, "could not initialise decoding engine") } @@ -987,7 +988,7 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR } // Bypass decoding codIOffset, _, err = arithmeticDecoder.DecodeBypass( - sliceContext.Slice.Data, + sliceContext.Slice.SliceData, codIRange, codIOffset, ) @@ -1018,9 +1019,9 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR logger.Printf("TODO: ae for MBType\n") } else { - sliceContext.Slice.Data.MbType = int(r.readUe()) + sliceContext.Slice.SliceData.MbType = int(r.readUe()) } - if sliceContext.Slice.Data.MbTypeName == "I_PCM" { + if sliceContext.Slice.SliceData.MbTypeName == "I_PCM" { for !br.ByteAligned() { _, err := br.ReadBits(1) if err != nil { @@ -1028,35 +1029,35 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR } } // 7-3 p95 - bitDepthY := 8 + sliceContext.SPS.BitDepthLumaMinus8 + bitDepthY := 8 + vid.SPS.BitDepthLumaMinus8 for i := 0; i < 256; i++ { s, err := br.ReadBits(int(bitDepthY)) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("could not read PcmSampleLuma[%d]", i)) } - sliceContext.Slice.Data.PcmSampleLuma = append( - sliceContext.Slice.Data.PcmSampleLuma, + sliceContext.Slice.SliceData.PcmSampleLuma = append( + sliceContext.Slice.SliceData.PcmSampleLuma, int(s)) } // 9.3.1 p 246 // cabac = initCabac(binarization, sliceContext) // 6-1 p 47 - mbWidthC := 16 / SubWidthC(sliceContext.SPS) - mbHeightC := 16 / SubHeightC(sliceContext.SPS) + mbWidthC := 16 / SubWidthC(vid.SPS) + mbHeightC := 16 / SubHeightC(vid.SPS) // if monochrome - if sliceContext.SPS.ChromaFormatIDC == chromaMonochrome || sliceContext.SPS.SeparateColorPlaneFlag { + if vid.SPS.ChromaFormatIDC == chromaMonochrome || vid.SPS.SeparateColorPlaneFlag { mbWidthC = 0 mbHeightC = 0 } - bitDepthC := 8 + sliceContext.SPS.BitDepthChromaMinus8 + bitDepthC := 8 + vid.SPS.BitDepthChromaMinus8 for i := 0; i < 2*mbWidthC*mbHeightC; i++ { s, err := br.ReadBits(int(bitDepthC)) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("could not read PcmSampleChroma[%d]", i)) } - sliceContext.Slice.Data.PcmSampleChroma = append( - sliceContext.Slice.Data.PcmSampleChroma, + sliceContext.Slice.SliceData.PcmSampleChroma = append( + sliceContext.Slice.SliceData.PcmSampleChroma, int(s)) } // 9.3.1 p 246 @@ -1064,32 +1065,32 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR } else { noSubMbPartSizeLessThan8x8Flag := 1 - m, err := MbPartPredMode(sliceContext.Slice.Data, sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType, 0) + m, err := MbPartPredMode(sliceContext.Slice.SliceData, sliceContext.Slice.SliceData.SliceTypeName, sliceContext.Slice.SliceData.MbType, 0) if err != nil { return nil, errors.Wrap(err, "could not get mbPartPredMode") } - if sliceContext.Slice.Data.MbTypeName == "I_NxN" && m != intra16x16 && NumMbPart(sliceContext.NALUnit, sliceContext.SPS, sliceContext.Slice.Header, sliceContext.Slice.Data) == 4 { + if sliceContext.Slice.SliceData.MbTypeName == "I_NxN" && m != intra16x16 && NumMbPart(sliceContext.NALUnit, vid.SPS, sliceContext.Slice.SliceHeader, sliceContext.Slice.SliceData) == 4 { logger.Printf("\tTODO: subMbPred\n") /* - subMbType := SubMbPred(sliceContext.Slice.Data.MbType) + subMbType := SubMbPred(sliceContext.Slice.SliceData.MbType) for mbPartIdx := 0; mbPartIdx < 4; mbPartIdx++ { if subMbType[mbPartIdx] != "B_Direct_8x8" { if NumbSubMbPart(subMbType[mbPartIdx]) > 1 { noSubMbPartSizeLessThan8x8Flag = 0 } - } else if !sliceContext.SPS.Direct8x8InferenceFlag { + } else if !vid.SPS.Direct8x8InferenceFlag { noSubMbPartSizeLessThan8x8Flag = 0 } } */ } else { - if sliceContext.PPS.Transform8x8Mode == 1 && sliceContext.Slice.Data.MbTypeName == "I_NxN" { + if vid.PPS.Transform8x8Mode == 1 && sliceContext.Slice.SliceData.MbTypeName == "I_NxN" { // TODO // 1 bit or ae(v) - // If sliceContext.PPS.EntropyCodingMode == 1, use ae(v) - if sliceContext.PPS.EntropyCodingMode == 1 { - binarization := NewBinarization("TransformSize8x8Flag", sliceContext.Slice.Data) - cabac = initCabac(binarization, sliceContext) + // If vid.PPS.EntropyCodingMode == 1, use ae(v) + if vid.PPS.EntropyCodingMode == 1 { + binarization := NewBinarization("TransformSize8x8Flag", sliceContext.Slice.SliceData) + cabac = initCabac(binarization, nil, sliceContext) binarization.Decode(sliceContext, br, nil) logger.Println("TODO: ae(v) for TransformSize8x8Flag") @@ -1098,22 +1099,22 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if err != nil { return nil, errors.Wrap(err, "could not read TransformSize8x8Flag") } - sliceContext.Slice.Data.TransformSize8x8Flag = b == 1 + sliceContext.Slice.SliceData.TransformSize8x8Flag = b == 1 } } // TODO: fix nil argument for. - MbPred(chromaArrayType, sliceContext, br, nil) + MbPred(chromaArrayType, nil, sliceContext, br, nil) } - m, err = MbPartPredMode(sliceContext.Slice.Data, sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType, 0) + m, err = MbPartPredMode(sliceContext.Slice.SliceData, sliceContext.Slice.SliceData.SliceTypeName, sliceContext.Slice.SliceData.MbType, 0) if err != nil { return nil, errors.Wrap(err, "could not get mbPartPredMode") } if m != intra16x16 { // TODO: me, ae logger.Printf("TODO: CodedBlockPattern pending me/ae implementation\n") - if sliceContext.PPS.EntropyCodingMode == 1 { - binarization := NewBinarization("CodedBlockPattern", sliceContext.Slice.Data) - cabac = initCabac(binarization, sliceContext) + if vid.PPS.EntropyCodingMode == 1 { + binarization := NewBinarization("CodedBlockPattern", sliceContext.Slice.SliceData) + cabac = initCabac(binarization, nil, sliceContext) // TODO: fix nil argument. binarization.Decode(sliceContext, br, nil) @@ -1123,17 +1124,17 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR br, uint(chromaArrayType), // TODO: fix this - //MbPartPredMode(sliceContext.Slice.Data, sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType, 0))) + //MbPartPredMode(sliceContext.Slice.SliceData, sliceContext.Slice.SliceData.SliceTypeName, sliceContext.Slice.SliceData.MbType, 0))) 0) - sliceContext.Slice.Data.CodedBlockPattern = int(me) + sliceContext.Slice.SliceData.CodedBlockPattern = int(me) } - // sliceContext.Slice.Data.CodedBlockPattern = me(v) | ae(v) - if CodedBlockPatternLuma(sliceContext.Slice.Data) > 0 && sliceContext.PPS.Transform8x8Mode == 1 && sliceContext.Slice.Data.MbTypeName != "I_NxN" && noSubMbPartSizeLessThan8x8Flag == 1 && (sliceContext.Slice.Data.MbTypeName != "B_Direct_16x16" || sliceContext.SPS.Direct8x8InferenceFlag) { + // sliceContext.Slice.SliceData.CodedBlockPattern = me(v) | ae(v) + if CodedBlockPatternLuma(sliceContext.Slice.SliceData) > 0 && vid.PPS.Transform8x8Mode == 1 && sliceContext.Slice.SliceData.MbTypeName != "I_NxN" && noSubMbPartSizeLessThan8x8Flag == 1 && (sliceContext.Slice.SliceData.MbTypeName != "B_Direct_16x16" || vid.SPS.Direct8x8InferenceFlag) { // TODO: 1 bit or ae(v) - if sliceContext.PPS.EntropyCodingMode == 1 { - binarization := NewBinarization("Transform8x8Flag", sliceContext.Slice.Data) - cabac = initCabac(binarization, sliceContext) + if vid.PPS.EntropyCodingMode == 1 { + binarization := NewBinarization("Transform8x8Flag", sliceContext.Slice.SliceData) + cabac = initCabac(binarization, nil, sliceContext) // TODO: fix nil argument. binarization.Decode(sliceContext, br, nil) @@ -1143,36 +1144,36 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if err != nil { return nil, errors.Wrap(err, "coult not read TransformSize8x8Flag") } - sliceContext.Slice.Data.TransformSize8x8Flag = b == 1 + sliceContext.Slice.SliceData.TransformSize8x8Flag = b == 1 } } } - m, err = MbPartPredMode(sliceContext.Slice.Data, sliceContext.Slice.Data.SliceTypeName, sliceContext.Slice.Data.MbType, 0) + m, err = MbPartPredMode(sliceContext.Slice.SliceData, sliceContext.Slice.SliceData.SliceTypeName, sliceContext.Slice.SliceData.MbType, 0) if err != nil { return nil, errors.Wrap(err, "could not get mbPartPredMode") } - if CodedBlockPatternLuma(sliceContext.Slice.Data) > 0 || CodedBlockPatternChroma(sliceContext.Slice.Data) > 0 || m == intra16x16 { + if CodedBlockPatternLuma(sliceContext.Slice.SliceData) > 0 || CodedBlockPatternChroma(sliceContext.Slice.SliceData) > 0 || m == intra16x16 { // TODO: se or ae(v) - if sliceContext.PPS.EntropyCodingMode == 1 { - binarization := NewBinarization("MbQpDelta", sliceContext.Slice.Data) - cabac = initCabac(binarization, sliceContext) + if vid.PPS.EntropyCodingMode == 1 { + binarization := NewBinarization("MbQpDelta", sliceContext.Slice.SliceData) + cabac = initCabac(binarization, nil, sliceContext) // TODO; fix nil argument binarization.Decode(sliceContext, br, nil) logger.Printf("TODO: ae for MbQpDelta\n") } else { - sliceContext.Slice.Data.MbQpDelta, _ = readSe(br) + sliceContext.Slice.SliceData.MbQpDelta, _ = readSe(br) } } } } // END MacroblockLayer - if sliceContext.PPS.EntropyCodingMode == 0 { + if vid.PPS.EntropyCodingMode == 0 { moreDataFlag = moreRBSPData(br) } else { - if sliceContext.Slice.Data.SliceTypeName != "I" && sliceContext.Slice.Data.SliceTypeName != "SI" { - if sliceContext.Slice.Data.MbSkipFlag { + if sliceContext.Slice.SliceData.SliceTypeName != "I" && sliceContext.Slice.SliceData.SliceTypeName != "SI" { + if sliceContext.Slice.SliceData.MbSkipFlag { prevMbSkipped = 1 } else { prevMbSkipped = 0 @@ -1186,17 +1187,17 @@ func NewSliceData(chromaArrayType int, sliceContext *SliceContext, br *bits.BitR if err != nil { return nil, errors.Wrap(err, "could not read EndOfSliceFlag") } - sliceContext.Slice.Data.EndOfSliceFlag = b == 1 - moreDataFlag = !sliceContext.Slice.Data.EndOfSliceFlag + sliceContext.Slice.SliceData.EndOfSliceFlag = b == 1 + moreDataFlag = !sliceContext.Slice.SliceData.EndOfSliceFlag } } - currMbAddr = nextMbAddress(currMbAddr, sliceContext.SPS, sliceContext.PPS, sliceContext.Slice.Header) + currMbAddr = nextMbAddress(currMbAddr, vid.SPS, vid.PPS, sliceContext.Slice.SliceHeader) } // END while moreDataFlag - return sliceContext.Slice.Data, nil + return sliceContext.Slice.SliceData, nil } func (c *SliceContext) Update(header *SliceHeader, data *SliceData) { - c.Slice = &Slice{Header: header, Data: data} + c.Slice = &Slice{SliceHeader: header, SliceData: data} } func NewSliceContext(vid *VideoStream, nalUnit *NALUnit, rbsp []byte, showPacket bool) (*SliceContext, error) { var err error @@ -1360,13 +1361,11 @@ func NewSliceContext(vid *VideoStream, nalUnit *NALUnit, rbsp []byte, showPacket sliceContext := &SliceContext{ NALUnit: nalUnit, - SPS: sps, - PPS: pps, Slice: &Slice{ - Header: &header, + SliceHeader: &header, }, } - sliceContext.Slice.Data, err = NewSliceData(vid.ChromaArrayType, sliceContext, br) + sliceContext.Slice.SliceData, err = NewSliceData(vid.ChromaArrayType, nil, sliceContext, br) if err != nil { return nil, errors.Wrap(err, "could not create slice data") } From 445649311b392c23793a52266e70326fb93f28e3 Mon Sep 17 00:00:00 2001 From: Saxon Date: Sun, 8 Sep 2019 12:53:25 +0930 Subject: [PATCH 06/18] codec/h264/h264dec/cavlc.go: added process to comgine level and run information --- codec/h264/h264dec/cavlc.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/codec/h264/h264dec/cavlc.go b/codec/h264/h264dec/cavlc.go index e1932548..9400ff43 100644 --- a/codec/h264/h264dec/cavlc.go +++ b/codec/h264/h264dec/cavlc.go @@ -127,3 +127,21 @@ func parseLevelInformation(br *bits.BitReader, totalCoeff, trailingOnes int) ([] } return levelVal, nil } + +// combineLevelRunInfo combines the level and run information obtained prior +// using the process defined in section 9.2.4 of the specifications and returns +// the corresponding coeffLevel list. +func combineLevelRunInfo(levelVal, runVal []int, totalCoeff int) []int { + coeffNum := -1 + i := totalCoeff - 1 + var coeffLevel []int + for j := 0; j < totalCoeff; j++ { + coeffNum += runVal[i] + 1 + if coeffNum >= len(coeffLevel) { + coeffLevel = append(coeffLevel, make([]int, (coeffNum+1)-len(coeffLevel))...) + } + coeffLevel[coeffNum] = levelVal[i] + i++ + } + return coeffLevel +} From 54fb4a551e90b6d1ecb9366d282a2ef889bf84f2 Mon Sep 17 00:00:00 2001 From: Alan Noble Date: Tue, 10 Sep 2019 09:54:54 +0100 Subject: [PATCH 07/18] Make up-to-date. --- go.sum | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/go.sum b/go.sum index c2d78459..a110fefb 100644 --- a/go.sum +++ b/go.sum @@ -1,50 +1,33 @@ bitbucket.org/ausocean/av v0.0.0-20190416003121-6ee286e98874/go.mod h1:DxZEprrNNQ2slHKAQVUHryDaWc5CbjxyHAvomhzg+AE= -bitbucket.org/ausocean/iot v1.2.4 h1:M/473iQ0d4q+76heerjAQuqXzQyc5dZ3F7Bfuq6X7q4= bitbucket.org/ausocean/iot v1.2.4/go.mod h1:5HVLgPHccW2PxS7WDUQO6sKWMgk3Vfze/7d5bHs8EWU= -bitbucket.org/ausocean/iot v1.2.5 h1:udD5X4oXUuKwdjO7bcq4StcDdjP8fJa2L0FnJJwF+6Q= -bitbucket.org/ausocean/iot v1.2.5/go.mod h1:dOclxXkdxAQGWO7Y5KcP1wpNfxg9oKUA2VqjJ3Le4RA= bitbucket.org/ausocean/iot v1.2.6 h1:KAAY1KZDbyOpoKajT1dM8BawupHiW9hUOelseSV1Ptc= bitbucket.org/ausocean/iot v1.2.6/go.mod h1:71AYHh8yGZ8XyzDBskwIWMF+8E8ORagXpXE24wlhoE0= bitbucket.org/ausocean/utils v0.0.0-20190408050157-66d3b4d4041e/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8= -bitbucket.org/ausocean/utils v1.2.4/go.mod h1:5JIXFTAMMNl5Ob79tpZfDCJ+gOO8rj7v4ORj56tHZpw= -bitbucket.org/ausocean/utils v1.2.6 h1:JN66APCV+hu6GebIHSu2KSywhLym4vigjSz5+fB0zXc= bitbucket.org/ausocean/utils v1.2.6/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8= -bitbucket.org/ausocean/utils v1.2.8 h1:wRlajOtaMz/loUrGmFf4SUcTnZALtTqgPmk49iHMWxs= +bitbucket.org/ausocean/utils v1.2.8 h1:hyxAIqYBqjqCguG+6A/kKyrAihyeUt2LziZg6CH0gLU= bitbucket.org/ausocean/utils v1.2.8/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 h1:LdOc9B9Bj6LEsKiXShkLA3/kpxXb6LJpH+ekU2krbzw= github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7/go.mod h1:O5HA0jgDXkBp+jw0770QNBT8fsRJCbH7JXmM7wxLUBU= -github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/adrianmo/go-nmea v1.1.1-0.20190109062325-c448653979f7/go.mod h1:HHPxPAm2kmev+61qmkZh7xgZF/7qHtSpsWppip2Ipv8= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-audio/aiff v0.0.0-20180403003018-6c3a8a6aff12/go.mod h1:AMSAp6W1zd0koOdX6QDgGIuBDTUvLa2SLQtm7d9eM3c= github.com/go-audio/audio v0.0.0-20180206231410-b697a35b5608/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs= -github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480 h1:4sGU+UABMMsRJyD+Y2yzMYxq0GJFUsRRESI0P1gZ2ig= github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs= -github.com/go-audio/wav v0.0.0-20181013172942-de841e69b884 h1:2TaXIaVA4ff/MHHezOj83tCypALTFAcXOImcFWNa3jw= github.com/go-audio/wav v0.0.0-20181013172942-de841e69b884/go.mod h1:UiqzUyfX0zs3pJ/DPyvS5v8sN6s5bXPUDDIVA5v8dks= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4/go.mod h1:2RvX5ZjVtsznNZPEt4xwJXNJrM3VTZoQf7V6gk0ysvs= github.com/kidoman/embd v0.0.0-20170508013040-d3d8c0c5c68d/go.mod h1:ACKj9jnzOzj1lw2ETilpFGK7L9dtJhAzT7T1OhAGtRQ= -github.com/mattetti/audio v0.0.0-20180912171649-01576cde1f21 h1:Hc1iKlyxNHp3CV59G2E/qabUkHvEwOIJxDK0CJ7CRjA= github.com/mattetti/audio v0.0.0-20180912171649-01576cde1f21/go.mod h1:LlQmBGkOuV/SKzEDXBPKauvN2UqCgzXO2XjecTGj40s= -github.com/mewkiz/flac v1.0.5 h1:dHGW/2kf+/KZ2GGqSVayNEhL9pluKn/rr/h/QqD9Ogc= github.com/mewkiz/flac v1.0.5/go.mod h1:EHZNU32dMF6alpurYyKHDLYpW1lYpBZ5WrXi/VuNIGs= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e h1:3NIzz7weXhh3NToPgbtlQtKiVgerEaG4/nY2skGoGG0= github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e/go.mod h1:CaowXBWOiSGWEpBBV8LoVnQTVPV4ycyviC9IBLj8dRw= @@ -53,14 +36,9 @@ go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/sys v0.0.0-20190305064518-30e92a19ae4a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From ecdaab175b098b4f86acab29d867bf36dfa3e3dd Mon Sep 17 00:00:00 2001 From: Saxon Date: Wed, 11 Sep 2019 09:47:37 +0930 Subject: [PATCH 08/18] codec/h264/parse.go: skip over access unit delimiters when getting nalType --- codec/h264/h264dec/frame.go | 2 +- codec/h264/parse.go | 39 +++++++++++++++++++++++-------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/codec/h264/h264dec/frame.go b/codec/h264/h264dec/frame.go index ca85982b..1904a09d 100644 --- a/codec/h264/h264dec/frame.go +++ b/codec/h264/h264dec/frame.go @@ -11,7 +11,7 @@ const ( naluTypeSEI NALTypeSPS naluTypePPS - naluTypeAccessUnitDelimiter + NALTypeAccessUnitDelimiter naluTypeEndOfSequence naluTypeEndOfStream naluTypeFillerData diff --git a/codec/h264/parse.go b/codec/h264/parse.go index 9465fb1c..accf68cf 100644 --- a/codec/h264/parse.go +++ b/codec/h264/parse.go @@ -26,34 +26,43 @@ LICENSE package h264 -import "errors" +import ( + "errors" + + "bitbucket.org/ausocean/av/codec/h264/h264dec" +) var errNotEnoughBytes = errors.New("not enough bytes to read") // NALType returns the NAL type of the given NAL unit bytes. The given NAL unit // may be in byte stream or packet format. +// NB: access unit delimiters are skipped. func NALType(n []byte) (int, error) { sc := frameScanner{buf: n} - b, ok := sc.readByte() - if !ok { - return 0, errNotEnoughBytes - } - for i := 1; b == 0x00 && i != 4; i++ { - b, ok = sc.readByte() + for { + b, ok := sc.readByte() if !ok { return 0, errNotEnoughBytes } - if b != 0x01 || (i != 2 && i != 3) { - continue - } + for i := 1; b == 0x00 && i != 4; i++ { + b, ok = sc.readByte() + if !ok { + return 0, errNotEnoughBytes + } + if b != 0x01 || (i != 2 && i != 3) { + continue + } - b, ok = sc.readByte() - if !ok { - return 0, errNotEnoughBytes + b, ok = sc.readByte() + if !ok { + return 0, errNotEnoughBytes + } + nalType := int(b & 0x1f) + if nalType != h264dec.NALTypeAccessUnitDelimiter { + return nalType, nil + } } - return int(b & 0x1f), nil } - return int(b & 0x1f), nil } type frameScanner struct { From e0509e7e615be3db87ce637e6b957c5e4ba741c4 Mon Sep 17 00:00:00 2001 From: Saxon Date: Wed, 11 Sep 2019 09:57:34 +0930 Subject: [PATCH 09/18] codec/containter/mts/encoder_test.go: fixed bug in test --- container/mts/encoder_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/container/mts/encoder_test.go b/container/mts/encoder_test.go index 47e9a809..6b46703e 100644 --- a/container/mts/encoder_test.go +++ b/container/mts/encoder_test.go @@ -101,7 +101,10 @@ func TestEncodeVideo(t *testing.T) { // Create the dst and write the test data to encoder. dst := &destination{} - _, err := NewEncoder(nopCloser{dst}, 25, EncodeH264).Write(data) + e := NewEncoder(nopCloser{dst}, 25, EncodeH264) + e.NALBasedPSI(false, psiSendCount) + + _, err := e.Write(data) if err != nil { t.Fatalf("could not write data to encoder, failed with err: %v\n", err) } From 0fd56675d50a7c1557ae9951a7f80472a9d74316 Mon Sep 17 00:00:00 2001 From: Saxon Date: Thu, 12 Sep 2019 13:24:44 +0930 Subject: [PATCH 10/18] updating go mod --- go.mod | 2 ++ go.sum | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/go.mod b/go.mod index adbdf113..d9fcfdaa 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,12 @@ go 1.12 require ( bitbucket.org/ausocean/iot v1.2.6 bitbucket.org/ausocean/utils v1.2.8 + github.com/BurntSushi/toml v0.3.1 // indirect github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480 github.com/go-audio/wav v0.0.0-20181013172942-de841e69b884 github.com/mewkiz/flac v1.0.5 github.com/pkg/errors v0.8.1 github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e + gopkg.in/yaml.v2 v2.2.2 // indirect ) diff --git a/go.sum b/go.sum index a110fefb..e840e715 100644 --- a/go.sum +++ b/go.sum @@ -6,28 +6,40 @@ bitbucket.org/ausocean/utils v0.0.0-20190408050157-66d3b4d4041e/go.mod h1:uXzX9z bitbucket.org/ausocean/utils v1.2.6/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8= bitbucket.org/ausocean/utils v1.2.8 h1:hyxAIqYBqjqCguG+6A/kKyrAihyeUt2LziZg6CH0gLU= bitbucket.org/ausocean/utils v1.2.8/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 h1:LdOc9B9Bj6LEsKiXShkLA3/kpxXb6LJpH+ekU2krbzw= github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7/go.mod h1:O5HA0jgDXkBp+jw0770QNBT8fsRJCbH7JXmM7wxLUBU= +github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/adrianmo/go-nmea v1.1.1-0.20190109062325-c448653979f7/go.mod h1:HHPxPAm2kmev+61qmkZh7xgZF/7qHtSpsWppip2Ipv8= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-audio/aiff v0.0.0-20180403003018-6c3a8a6aff12/go.mod h1:AMSAp6W1zd0koOdX6QDgGIuBDTUvLa2SLQtm7d9eM3c= github.com/go-audio/audio v0.0.0-20180206231410-b697a35b5608/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs= +github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480 h1:4sGU+UABMMsRJyD+Y2yzMYxq0GJFUsRRESI0P1gZ2ig= github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs= +github.com/go-audio/wav v0.0.0-20181013172942-de841e69b884 h1:2TaXIaVA4ff/MHHezOj83tCypALTFAcXOImcFWNa3jw= github.com/go-audio/wav v0.0.0-20181013172942-de841e69b884/go.mod h1:UiqzUyfX0zs3pJ/DPyvS5v8sN6s5bXPUDDIVA5v8dks= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4/go.mod h1:2RvX5ZjVtsznNZPEt4xwJXNJrM3VTZoQf7V6gk0ysvs= github.com/kidoman/embd v0.0.0-20170508013040-d3d8c0c5c68d/go.mod h1:ACKj9jnzOzj1lw2ETilpFGK7L9dtJhAzT7T1OhAGtRQ= +github.com/mattetti/audio v0.0.0-20180912171649-01576cde1f21 h1:Hc1iKlyxNHp3CV59G2E/qabUkHvEwOIJxDK0CJ7CRjA= github.com/mattetti/audio v0.0.0-20180912171649-01576cde1f21/go.mod h1:LlQmBGkOuV/SKzEDXBPKauvN2UqCgzXO2XjecTGj40s= +github.com/mewkiz/flac v1.0.5 h1:dHGW/2kf+/KZ2GGqSVayNEhL9pluKn/rr/h/QqD9Ogc= github.com/mewkiz/flac v1.0.5/go.mod h1:EHZNU32dMF6alpurYyKHDLYpW1lYpBZ5WrXi/VuNIGs= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e h1:3NIzz7weXhh3NToPgbtlQtKiVgerEaG4/nY2skGoGG0= github.com/yobert/alsa v0.0.0-20180630182551-d38d89fa843e/go.mod h1:CaowXBWOiSGWEpBBV8LoVnQTVPV4ycyviC9IBLj8dRw= @@ -40,5 +52,9 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/sys v0.0.0-20190305064518-30e92a19ae4a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 9769a3c4a9ae2137fefd7891e5b26efbf74dc61c Mon Sep 17 00:00:00 2001 From: Saxon Date: Thu, 12 Sep 2019 17:08:22 +0930 Subject: [PATCH 11/18] revid: not setting up pipeline until we start --- revid/revid.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index fa1156b1..6f697bd0 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -119,10 +119,6 @@ type Revid struct { // an error if construction of the new instance was not successful. func New(c Config, ns *netsender.Sender) (*Revid, error) { r := Revid{ns: ns, err: make(chan error)} - err := r.reset(c) - if err != nil { - return nil, err - } go r.handleErrors() return &r, nil } @@ -317,12 +313,17 @@ func (r *Revid) Start() error { } r.config.Logger.Log(logger.Info, pkg+"starting Revid") r.isRunning = true - var err error + err := r.reset(r.config) + if err != nil { + r.Stop() + return err + } r.closeInput, err = r.setupInput() if err != nil { r.Stop() + return err } - return err + return nil } // Stop closes down the pipeline. This closes encoders and sender output routines, @@ -543,7 +544,7 @@ func (r *Revid) Update(vars map[string]string) error { } } r.config.Logger.Log(logger.Info, pkg+"revid config changed", "config", fmt.Sprintf("%+v", r.config)) - return r.reset(r.config) + return nil } // startRaspivid sets up things for input from raspivid i.e. starts From fe49be41ad8554bac9dec5de627f9ee0cbc40489 Mon Sep 17 00:00:00 2001 From: Saxon Milton Date: Thu, 12 Sep 2019 07:47:46 +0000 Subject: [PATCH 12/18] revid: setting revid's config in revid.New --- revid/revid.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/revid/revid.go b/revid/revid.go index 6f697bd0..0f357ebd 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -119,6 +119,11 @@ type Revid struct { // an error if construction of the new instance was not successful. func New(c Config, ns *netsender.Sender) (*Revid, error) { r := Revid{ns: ns, err: make(chan error)} + err := r.setConfig(c) + if err != nil { + return nil, fmt.Errorf("could not set config, failed with error: %v",err) + } + r.config.Logger.SetLevel(c.LogLevel) go r.handleErrors() return &r, nil } From 96035f6d8b742b30e900d0a31a38a55c5b334b3d Mon Sep 17 00:00:00 2001 From: Trek H Date: Thu, 12 Sep 2019 19:16:11 +0930 Subject: [PATCH 13/18] adpcm and mts: comments and pid change --- codec/adpcm/adpcm.go | 2 +- container/mts/encoder.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/codec/adpcm/adpcm.go b/codec/adpcm/adpcm.go index 479f6261..b61d9fee 100644 --- a/codec/adpcm/adpcm.go +++ b/codec/adpcm/adpcm.go @@ -369,7 +369,7 @@ func capAdd16(a, b int16) int16 { // EncBytes will return the number of adpcm bytes that will be generated when encoding the given amount of pcm bytes (n). func EncBytes(n int) int { // For 'n' pcm bytes, 1 sample is left uncompressed, the rest is compressed by a factor of 4 - // and a start index and padding-flag byte are added. + // and a chunk length (4B), start index (1B) and padding-flag (1B) are added. // Also if there are an even number of samples, there will be half a byte of padding added to the last byte. if n%bytesPerEnc == 0 { return (n-byteDepth)/compFact + headSize + 1 diff --git a/container/mts/encoder.go b/container/mts/encoder.go index 7d968d5f..9bc2ca44 100644 --- a/container/mts/encoder.go +++ b/container/mts/encoder.go @@ -44,7 +44,7 @@ import ( const ( H264ID = 27 H265ID = 36 - audioStreamID = 0xc0 // First audio stream ID. + audioStreamID = 0xc0 // ADPCM audio stream ID. ) // Constants used to communicate which media codec will be packetized. @@ -168,7 +168,7 @@ func NewEncoder(dst io.WriteCloser, rate float64, mediaType int) *Encoder { Pil: 0, Essd: &psi.ESSD{ St: byte(sid), - Epid: 0x0100, + Epid: byte(mPid), Esil: 0x00, }, } From e7a02a818f94ba5d9ce7fd40a2af12ea2caa40af Mon Sep 17 00:00:00 2001 From: Trek H Date: Thu, 12 Sep 2019 21:29:40 +0930 Subject: [PATCH 14/18] mts: fixed type conversion --- container/mts/encoder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/container/mts/encoder.go b/container/mts/encoder.go index 9bc2ca44..3249ce56 100644 --- a/container/mts/encoder.go +++ b/container/mts/encoder.go @@ -168,7 +168,7 @@ func NewEncoder(dst io.WriteCloser, rate float64, mediaType int) *Encoder { Pil: 0, Essd: &psi.ESSD{ St: byte(sid), - Epid: byte(mPid), + Epid: uint16(mPid), Esil: 0x00, }, } From c3df750175a7968c8cee0802e16fc1f552e4a4ba Mon Sep 17 00:00:00 2001 From: Trek H Date: Thu, 12 Sep 2019 23:12:55 +0930 Subject: [PATCH 15/18] mts: set nalbasedpsi to false for audio --- container/mts/encoder.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/container/mts/encoder.go b/container/mts/encoder.go index 3249ce56..693b0be3 100644 --- a/container/mts/encoder.go +++ b/container/mts/encoder.go @@ -150,10 +150,12 @@ type Encoder struct { func NewEncoder(dst io.WriteCloser, rate float64, mediaType int) *Encoder { var mPid int var sid byte + nbp := true switch mediaType { case EncodeAudio: mPid = AudioPid sid = audioStreamID + nbp = false case EncodeH265: mPid = VideoPid sid = H265ID @@ -180,7 +182,7 @@ func NewEncoder(dst io.WriteCloser, rate float64, mediaType int) *Encoder { writePeriod: time.Duration(float64(time.Second) / rate), ptsOffset: ptsOffset, - nalBasedPSI: true, + nalBasedPSI: nbp, pktCount: 8, From 6f6f24b8418c27d72eab08b841ba0088ada0a7d8 Mon Sep 17 00:00:00 2001 From: scruzin Date: Fri, 13 Sep 2019 17:32:23 +0930 Subject: [PATCH 16/18] Use ausocean/utils v1.2.9. --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index d9fcfdaa..e227992d 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.12 require ( bitbucket.org/ausocean/iot v1.2.6 - bitbucket.org/ausocean/utils v1.2.8 + bitbucket.org/ausocean/utils v1.2.9 github.com/BurntSushi/toml v0.3.1 // indirect github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 github.com/go-audio/audio v0.0.0-20181013203223-7b2a6ca21480 diff --git a/go.sum b/go.sum index e840e715..0ff043ea 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ bitbucket.org/ausocean/utils v0.0.0-20190408050157-66d3b4d4041e/go.mod h1:uXzX9z bitbucket.org/ausocean/utils v1.2.6/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8= bitbucket.org/ausocean/utils v1.2.8 h1:hyxAIqYBqjqCguG+6A/kKyrAihyeUt2LziZg6CH0gLU= bitbucket.org/ausocean/utils v1.2.8/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8= +bitbucket.org/ausocean/utils v1.2.9 h1:g45C6KCNvCLOGFv+ZnmDbQOOdnwpIsvzuNOD141CTVI= +bitbucket.org/ausocean/utils v1.2.9/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 h1:LdOc9B9Bj6LEsKiXShkLA3/kpxXb6LJpH+ekU2krbzw= From f32ef802476446ce13b1789ba5e34a400cffe8fd Mon Sep 17 00:00:00 2001 From: scruzin Date: Sat, 14 Sep 2019 11:59:17 +0930 Subject: [PATCH 17/18] Use ausocean/utils v1.2.9. --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index e227992d..2ff6894f 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module bitbucket.org/ausocean/av go 1.12 require ( - bitbucket.org/ausocean/iot v1.2.6 + bitbucket.org/ausocean/iot v1.2.7 bitbucket.org/ausocean/utils v1.2.9 github.com/BurntSushi/toml v0.3.1 // indirect github.com/Comcast/gots v0.0.0-20190305015453-8d56e473f0f7 diff --git a/go.sum b/go.sum index 0ff043ea..c7035a5d 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ bitbucket.org/ausocean/av v0.0.0-20190416003121-6ee286e98874/go.mod h1:DxZEprrNN bitbucket.org/ausocean/iot v1.2.4/go.mod h1:5HVLgPHccW2PxS7WDUQO6sKWMgk3Vfze/7d5bHs8EWU= bitbucket.org/ausocean/iot v1.2.6 h1:KAAY1KZDbyOpoKajT1dM8BawupHiW9hUOelseSV1Ptc= bitbucket.org/ausocean/iot v1.2.6/go.mod h1:71AYHh8yGZ8XyzDBskwIWMF+8E8ORagXpXE24wlhoE0= +bitbucket.org/ausocean/iot v1.2.7 h1:dZgrmVtuXnzHgybDthn0bYgAJms9euTONXBsqsx9g5M= +bitbucket.org/ausocean/iot v1.2.7/go.mod h1:aAWgPo2f8sD2OPmxae1E5/iD9+tKY/iW4pcQMQXUvHM= bitbucket.org/ausocean/utils v0.0.0-20190408050157-66d3b4d4041e/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8= bitbucket.org/ausocean/utils v1.2.6/go.mod h1:uXzX9z3PLemyURTMWRhVI8uLhPX4uuvaaO85v2hcob8= bitbucket.org/ausocean/utils v1.2.8 h1:hyxAIqYBqjqCguG+6A/kKyrAihyeUt2LziZg6CH0gLU= From 751ee29c79d3fc833f191ef3b0b88d295b470d69 Mon Sep 17 00:00:00 2001 From: Trek H Date: Sat, 14 Sep 2019 20:01:44 +0930 Subject: [PATCH 18/18] removed audio-player files --- cmd/audio-player/adpcm.js | 147 --------------------------------- cmd/audio-player/favicon.ico | Bin 15406 -> 0 bytes cmd/audio-player/index.html | 44 ---------- cmd/audio-player/main.js | 104 ----------------------- cmd/audio-player/pcm-to-wav.js | 64 -------------- 5 files changed, 359 deletions(-) delete mode 100644 cmd/audio-player/adpcm.js delete mode 100644 cmd/audio-player/favicon.ico delete mode 100644 cmd/audio-player/index.html delete mode 100644 cmd/audio-player/main.js delete mode 100644 cmd/audio-player/pcm-to-wav.js diff --git a/cmd/audio-player/adpcm.js b/cmd/audio-player/adpcm.js deleted file mode 100644 index 958a295c..00000000 --- a/cmd/audio-player/adpcm.js +++ /dev/null @@ -1,147 +0,0 @@ -/* -NAME - adpcm.js - -AUTHOR - Trek Hopton - -LICENSE - This file is Copyright (C) 2018 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 [GNU licenses](http://www.gnu.org/licenses). -*/ - -/* - Original IMA/DVI ADPCM specification: (http://www.cs.columbia.edu/~hgs/audio/dvi/IMA_ADPCM.pdf). - Reference algorithms for ADPCM compression and decompression are in part 6. -*/ - -// Table of index changes (see spec). -const indexTable = [ - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8 -]; - -// Quantize step size table (see spec). -const stepTable = [ - 7, 8, 9, 10, 11, 12, 13, 14, - 16, 17, 19, 21, 23, 25, 28, 31, - 34, 37, 41, 45, 50, 55, 60, 66, - 73, 80, 88, 97, 107, 118, 130, 143, - 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, - 724, 796, 876, 963, 1060, 1166, 1282, 1411, - 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, - 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, - 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, - 32767 -]; - -const byteDepth = 2, // We are working with 16-bit samples. TODO(Trek): make configurable. - headSize = 8, // Number of bytes in the header of ADPCM. - chunkLenSize = 4; - -let est = 0, // Estimation of sample based on quantised ADPCM nibble. - idx = 0, // Index to step used for estimation. - step = 0; - -// decodeSample takes 4 bits which represents a single ADPCM nibble, and returns a 16 bit decoded PCM sample. -function decodeSample(nibble) { - let diff = 0; - if ((nibble & 4) != 0) { - diff += step; - } - if ((nibble & 2) != 0) { - diff += step >> 1; - } - if ((nibble & 1) != 0) { - diff += step >> 2; - } - diff += step >> 3; - - if ((nibble & 8) != 0) { - diff = -diff; - } - est += diff; - idx += indexTable[nibble]; - - if (idx < 0) { - idx = 0; - } else if (idx > stepTable.length - 1) { - idx = stepTable.length - 1; - } - - step = stepTable[idx]; - - result = est; - return result; -} - -// decode takes an array of bytes of arbitrary length representing adpcm and decodes it into pcm. -function decode(b) { - // Iterate over each chunk and decode it. - let chunkLen; - var result = []; - for (var off = 0; off + headSize <= b.length; off += chunkLen) { - // Read length of chunk and check if whole chunk exists. - chunkLen = bytesToInt32(b.slice(off, off + chunkLenSize)) - if (off + chunkLen > b.length) { - break; - } - - // Initialize Decoder with first 4 bytes of b. - est = bytesToInt16(b.slice(off + chunkLenSize, off + chunkLenSize + byteDepth)); - idx = b[off + chunkLenSize + byteDepth]; - step = stepTable[idx]; - - result.push(...b.slice(off + chunkLenSize, off + chunkLenSize + byteDepth)); - - for (var i = off + headSize; i < off + chunkLen - b[off + chunkLenSize + 3]; i++) { - var twoNibs = b[i]; - var nib2 = twoNibs >> 4; - var nib1 = (nib2 << 4) ^ twoNibs; - - var sample1 = int16ToBytes(decodeSample(nib1)); - result.push(...sample1); - - var sample2 = int16ToBytes(decodeSample(nib2)); - result.push(...sample2); - } - if (b[off + chunkLenSize + 3] == 1) { - var padNib = b[off + chunkLen - 1]; - var sample = int16ToBytes(decodeSample(padNib)); - result.push(...sample); - } - } - return result; -} - -// int16ToBytes takes a number assumed to be an int 16 and converts it to an array containing bytes (Little Endian). -function int16ToBytes(num) { - return [(num & 0x00ff), (num & 0xff00) >> 8]; -} - -// bytesToInt16 takes an array of bytes (assumed to be values between 0 and 255), interprates them as little endian and converts it to an int16. -function bytesToInt16(b) { - return (b[0] | (b[1] << 8)); -} - -// bytesToInt32 takes an array of bytes (assumed to be values between 0 and 255), interprates them as little endian and converts it to an int32. -function bytesToInt32(b) { - return (b[0] | - (b[1] << 8) | - (b[2] << 16) | - (b[3] << 24)); -} \ No newline at end of file diff --git a/cmd/audio-player/favicon.ico b/cmd/audio-player/favicon.ico deleted file mode 100644 index 465b02c257d3a5388ce1a7744355834fbd37fa82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15406 zcmeHO32>9w5f(`rkPoo2&0#KI_`sKBUAAobKJh78zp*UIwk+SqMihrYN+u3zVIXPK z5E?oyB?U5cI-zMMkf8xmAS6Ii8X%;!C8VSrA($)J@olu-C+n7sEL)b%6wU1Xzx4m_ z?f3TW+ugVOM59fiJxTNMpyAbzR{s=@#--6{ettvWLp^D<9rzoAp?w}qqn+@f(L(VZ zY=SL@e#gtOA4yJVQi)*B-V(mo1xe!U%MT+eZss{j(!3p&`H_SLtuiM(U&L|iDTpZWS99@AZ$On5m%1_JWHS zV&Kkg4ieXbZnv{x*RO)GkExn|gltzRV!42b<9?a&-n=#t)aobz7@n?Q4MS{nc)npC zoIA|`Wv-XL{maiSerQ|L@BQy1;BTKq!r)*u3=Bj;b)J3gjj>Hc`_7I?lra+?JczQu zzj*mP%psSJZC3!{=HLO9f;{h=Oen`nk#6FGWBbR5os%i?;6?x2c zva|)iSLQD{Sd+ix=vb&c)BoLytdMOD(u}6njlwV@7b{q%D5*GZS$e=BA;+yt7(=&P z?lxqsM%yqTj`MC;(K#D^>GgFq@1cGSlxKzQ(_vVp z6fIgNnENI6HSWCicoBm%J!Eroa`IDE1&p>L7JX3v%uatX+IHetuiLE+#Zi(J|Ffg* zV=V1Z9|r465?f0Iz5`?FXDn^yX$#-f`7T{QLKYqEsVgjtcSCZwgWNRjh`-hKW$Rjz z8+OpZe=1OM9LE?oMz04dQ95@0(X?0h2}ZS@SqFyxaTh5_T6qsGs-ycCIk zf@#y|82e1)d*bW+`l8|2n?tP1fcTN(*qQogC2ymdGThEvBwK^$wC z2O^J+tE1rTX)ZjY^s~+%{oL^n6K%#DIzA7(o;w`?C2@41V%^|{mc?-9GZysrFoF2n zwRMZeo&WhWLGY7$e;f}Rx_)5kWlG`zXYlXrWI|^LThCV~D`)Z7@iV_Z=I@;OHNO@U% zkH~xXwg}t@80Z?mA|eze_m?`|~w^#B(t zvwieDjQy+m{gD4N_0wXWD@ar3f-K$NZjz?X0Wr^IM7#+WNy>sFx;%k7HfMZS zNeyUs1}{qo<%MYjiRYnD#0Dr6!C_s;R13;Kg) zf;pF!MXaK>Hrf+9{^UwgOP+3&q~=#-1s^C8%)jqQS>U)Hpsro5E@Ez3(NGYA?4}s= z{(rtFc@j*~(khWgnkT_mH6Jo(t5=u$)|Frx#N%Nb0YHMqM zw6causuprSB6%(??qO|}wtuHS$9(D_=0vVGE=ycvHijpfWm(Z!SNIF&XL~hcc2cg$ zPC2MC_8Kfr@cl-S&#jYZMrm}3_?oIb#%7!&;_D_#S4KLQ8hxVTXPqT}stwn4i!75b zNm+EB=$W1J7%5MOzbC@=pva4UU8Sn@XcWh<7joQ*Uz_Z*H^>2HElUqL)l`umuE=Md zB)R=ZMfO^pYOKZGuA>sNIPYjlPy5ZowbFGCJ|@GkewYTKI1j7Xp6d4 z6&ag`@}Z`Cts$Ny-|Ggll<7z_kUShjGoUO9>uIrA6CH!h&`-A`MSpUr(ruQYYxZc`ad#Tu^*tZR&b zbAL~S&Q2B#V7_KxfZH|kU z;A!&RBRdpv@Xg#hhYUj9e!LMhV^c)!)0!a zU3cH#7Xb&~TL@)|2Hha_it60i@Y?!dICeM@Zr@_V_xBj^+J*?MJ(!Gh82n2RKhHV% z`y=4cz6BcmBrhgQ@q`U)m~i442kza)HK)y$c6LS~{_shO|M2?@p(fuOo^J|-gZntp z{#~3!j(4)+9~g*)bDu}T{=Gc-&sS{d>1Jrodzjmd$%=ny4Ktt*YlGyRiaBoGI+?8a zb@*&uALDnt53?n68UIlH=7O=A8?;D#;SW1_aPgm9 z97hb+c87GzKKxFOpSAHP*}n+cSbI$LfHgIX;hjAk`1-4OO-$6$G4l9RB@0HK&4jZPySFUFvS0wabPShN%DkM6+!Uc+dPctS?~+o$JmVjQ3i?}Up%+W z#u z+w$_v--u&7zZAsm#uC2sLN9Puhz@blUI~yHWu?d?;!q1ss1t`P4)XgRh1jitjJj+&j>k+ z|L>Ww^V)XKy;{WcxT`GStZQqlb!n@ub*T}>HsiVX8;`&okpD~c;@SKIN+CZ2i`bg; zBG1)|<~GVww&Qc3X=}Z37DeG7J0E`@OTd8=_#Y2!$T$E1 diff --git a/cmd/audio-player/index.html b/cmd/audio-player/index.html deleted file mode 100644 index c7d7ab04..00000000 --- a/cmd/audio-player/index.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - Audio Player - - - - - - - -
-
-
- URL: -
-
- -
-
-
-
-
- -
-
-
- -
-
-
-
-
- ©2019 Australian Ocean Laboratory Limited (AusOcean) (License) -
-
- - - \ No newline at end of file diff --git a/cmd/audio-player/main.js b/cmd/audio-player/main.js deleted file mode 100644 index 3606a653..00000000 --- a/cmd/audio-player/main.js +++ /dev/null @@ -1,104 +0,0 @@ -/* -NAME - main.js - -AUTHOR - Trek Hopton - Alan Noble - -LICENSE - This file is Copyright (C) 2018 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 [GNU licenses](http://www.gnu.org/licenses). -*/ - -function processData() { - const input = event.target.files[0] - const reader = new FileReader() - - reader.onload = event => { - bytes = new Uint8Array(event.target.result) - - // decode adpcm to pcm - var decoded = decode(Array.from(bytes)) - - // convert raw pcm to wav TODO(Trek): make these configurable. - var wav = pcmToWav(decoded, 48000, 1, 16); - - // play wav data in player - const blob = new Blob([Uint8Array.from(wav)], { - type: 'audio/wav' - }); - const url = URL.createObjectURL(blob); - - const audio = document.getElementById('audio'); - const source = document.getElementById('source'); - - source.src = url; - audio.load(); - audio.play(); - } - reader.onerror = error => reject(error) - reader.readAsArrayBuffer(input) - -} - -// getQuery gets everything after the question mark in the URL. -function getQuery() { - var regex = new RegExp("\\?(.*)"); - var match = regex.exec(window.location.href); - if (match == null) { - return ''; - } else { - return decodeURIComponent(match[1].replace(/\+/g, " ")); - } -} - -function load() { - var url = document.getElementById('url').value; - if (url == "") { - url = getQuery() - document.getElementById('url').value = url; - } - if (url[0] == '/') { - url = window.location.protocol + '//' + window.location.host + url; - } - if (url == "") { - return; - } - - var request = new XMLHttpRequest(); - request.responseType = "blob"; - request.onreadystatechange = function () { - if (request.readyState === XMLHttpRequest.DONE) { - if (request.status === 200) { - console.log("request received"); - - data = request.response; - - dataURL = URL.createObjectURL(data); - - var link = document.getElementById("link"); - link.href = dataURL; - link.download = "media.ts"; - link.innerHTML = "Download"; - - } else { - console.log('There was a problem with the request.'); - } - } - } - request.open("GET", url, true); - request.send(); -} \ No newline at end of file diff --git a/cmd/audio-player/pcm-to-wav.js b/cmd/audio-player/pcm-to-wav.js deleted file mode 100644 index a9f368ca..00000000 --- a/cmd/audio-player/pcm-to-wav.js +++ /dev/null @@ -1,64 +0,0 @@ -/* -NAME - pcm-to-wav.js - -AUTHOR - Trek Hopton - -LICENSE - This file is Copyright (C) 2018 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 [GNU licenses](http://www.gnu.org/licenses). -*/ - -// pcmToWav takes raw pcm data along with the sample rate, number of channels and bit-depth, -// and adds a WAV header to it so that it can be read and played by common players. -// input and output data bytes are represented as arrays of 8 bit integers. -// WAV spec.: http://soundfile.sapp.org/doc/WaveFormat/ -function pcmToWav(data, rate, channels, bitdepth) { - subChunk2ID = [100, 97, 116, 97]; // "data" - subChunk2Size = int32ToBytes(data.length); - - subChunk1ID = [102, 109, 116, 32]; // "fmt " - subChunk1Size = int32ToBytes(16); - audioFmt = int16ToBytes(1); // 1 = PCM - numChannels = int16ToBytes(channels); - sampleRate = int32ToBytes(rate); - byteRate = int32ToBytes(rate * channels * bitdepth / 8); - blockAlign = int16ToBytes(channels * bitdepth / 8); - bitsPerSample = int16ToBytes(bitdepth) - - chunkID = [82, 73, 70, 70]; // "RIFF" - chunkSize = int32ToBytes(36 + data.length); - format = [87, 65, 86, 69]; // "WAVE" - - result = chunkID; - result.push(...chunkSize, ...format, ...subChunk1ID, ...subChunk1Size, ...audioFmt, ...numChannels, ...sampleRate, ...byteRate, ...blockAlign, ...bitsPerSample, ...subChunk2ID, ...subChunk2Size); - return result.concat(data); -} - -// int32ToBytes takes a number assumed to be an int 32 and converts it to an array containing bytes (Little Endian). -function int32ToBytes(num) { - return [ - (num & 0x000000ff), - (num & 0x0000ff00) >> 8, - (num & 0x00ff0000) >> 16, - (num & 0xff000000) >> 24 - ]; -} - -// int16ToBytes takes a number assumed to be an int 16 and converts it to an array containing bytes (Little Endian). -function int16ToBytes(num) { - return [(num & 0x00ff), (num & 0xff00) >> 8]; -} \ No newline at end of file