mirror of https://bitbucket.org/ausocean/av.git
148 lines
4.6 KiB
Go
148 lines
4.6 KiB
Go
|
package h264dec
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"errors"
|
||
|
"reflect"
|
||
|
"testing"
|
||
|
|
||
|
"bitbucket.org/ausocean/av/codec/h264/h264dec/bits"
|
||
|
)
|
||
|
|
||
|
func TestNewPPS(t *testing.T) {
|
||
|
// TODO: add test with scaling list once we have a test for scalingList func.
|
||
|
tests := []struct {
|
||
|
in string
|
||
|
chromaFormat int
|
||
|
want PPS
|
||
|
}{
|
||
|
{
|
||
|
in: "1" + // ue(v) pic_parameter_set_id = 0
|
||
|
"1" + // ue(v) seq_parameter_set_id = 0
|
||
|
"1" + // u(1) entropy_coding_mode_flag = 1
|
||
|
"0" + // u(1) pic_order_present_flag = 0
|
||
|
"1" + // ue(v) num_slice_groups_minus1 = 0
|
||
|
"1" + // ue(v) num_ref_idx_L0_active_minus1 = 0
|
||
|
"1" + // ue(v) num_ref_idx_L1_active_minus1 = 0
|
||
|
"1" + // u(1) weighted_pred_flag = 1
|
||
|
"00" + // u(2) weighted_bipred_idc = 0
|
||
|
"1" + // se(v) pic_init_qp_minus26 = 0
|
||
|
"1" + // se(v) pic_init_qs_minus26 = 0
|
||
|
"1" + // se(v) chroma_qp_index_offset = 0
|
||
|
"1" + // u(1) deblocking_filter_control_present_flag = 1
|
||
|
"0" + // u(1) constrained_intra_pred_flag = 0
|
||
|
"0" + // u(1) redundant_pic_cnt_present_flag = 0
|
||
|
"10000000", // rbspTrailingBits
|
||
|
want: PPS{
|
||
|
ID: 0,
|
||
|
SPSID: 0,
|
||
|
EntropyCodingMode: 1,
|
||
|
BottomFieldPicOrderInFramePresent: false,
|
||
|
NumSliceGroupsMinus1: 0,
|
||
|
NumRefIdxL0DefaultActiveMinus1: 0,
|
||
|
NumRefIdxL1DefaultActiveMinus1: 0,
|
||
|
WeightedPred: true,
|
||
|
WeightedBipred: 0,
|
||
|
PicInitQpMinus26: 0,
|
||
|
PicInitQsMinus26: 0,
|
||
|
ChromaQpIndexOffset: 0,
|
||
|
DeblockingFilterControlPresent: true,
|
||
|
ConstrainedIntraPred: false,
|
||
|
RedundantPicCntPresent: false,
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
in: "1" + // ue(v) pic_parameter_set_id = 0
|
||
|
"1" + // ue(v) seq_parameter_set_id = 0
|
||
|
"1" + // u(1) entropy_coding_mode_flag = 1
|
||
|
"1" + // u(1) bottom_field_pic_order_in_frame_present_flag = 1
|
||
|
"010" + // ue(v) num_slice_groups_minus1 = 1
|
||
|
"1" + // ue(v) slice_group_map_type = 0
|
||
|
"1" + // ue(v) run_length_minus1[0] = 0
|
||
|
"1" + // ue(v) run_length_minus1[1] = 0
|
||
|
"1" + // ue(v) num_ref_idx_L0_active_minus1 = 0
|
||
|
"1" + // ue(v) num_ref_idx_L1_active_minus1 = 0
|
||
|
"1" + // u(1) weighted_pred_flag = 0
|
||
|
"00" + // u(2) weighted_bipred_idc = 0
|
||
|
"011" + // se(v) pic_init_qp_minus26 = -1
|
||
|
"010" + // se(v) pic_init_qs_minus26 = 1
|
||
|
"00100" + // se(v) chroma_qp_index_offset = 2
|
||
|
"0" + // u(1) deblocking_filter_control_present_flag =0
|
||
|
"0" + // u(1) constrained_intra_pred_flag=0
|
||
|
"0" + // u(1) redundant_pic_cnt_present_flag=0
|
||
|
"0" + // u(1) transform_8x8_mode_flag=0
|
||
|
"0" + // u(1) pic_scaling_matrix_present_flag=0
|
||
|
"00100" + // se(v) second_chroma_qp_index_offset=2
|
||
|
"10000", // stop bit and trailing bits
|
||
|
want: PPS{
|
||
|
ID: 0,
|
||
|
SPSID: 0,
|
||
|
EntropyCodingMode: 1,
|
||
|
BottomFieldPicOrderInFramePresent: true,
|
||
|
NumSliceGroupsMinus1: 1,
|
||
|
RunLengthMinus1: []int{0, 0},
|
||
|
NumRefIdxL0DefaultActiveMinus1: 0,
|
||
|
NumRefIdxL1DefaultActiveMinus1: 0,
|
||
|
WeightedPred: true,
|
||
|
WeightedBipred: 0,
|
||
|
PicInitQpMinus26: -1,
|
||
|
PicInitQsMinus26: 1,
|
||
|
ChromaQpIndexOffset: 2,
|
||
|
DeblockingFilterControlPresent: false,
|
||
|
ConstrainedIntraPred: false,
|
||
|
RedundantPicCntPresent: false,
|
||
|
Transform8x8Mode: 0,
|
||
|
PicScalingMatrixPresent: false,
|
||
|
SecondChromaQpIndexOffset: 2,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for i, test := range tests {
|
||
|
bin, err := binToSlice(test.in)
|
||
|
if err != nil {
|
||
|
t.Fatalf("error: %v converting binary string to slice for test: %d", err, i)
|
||
|
}
|
||
|
|
||
|
pps, err := NewPPS(bits.NewBitReader(bytes.NewReader(bin)), test.chromaFormat)
|
||
|
if err != nil {
|
||
|
t.Fatalf("did not expect error: %v for test: %d", err, i)
|
||
|
}
|
||
|
|
||
|
if !reflect.DeepEqual(test.want, *pps) {
|
||
|
t.Errorf("did not get expected result for test: %d.\nGot: %+v\nWant: %+v\n", i, *pps, test.want)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// binToSlice is a helper function to convert a string of binary into a
|
||
|
// corresponding byte slice, e.g. "0100 0001 1000 1100" => {0x41,0x8c}.
|
||
|
// Spaces in the string are ignored.
|
||
|
func binToSlice(s string) ([]byte, error) {
|
||
|
var (
|
||
|
a byte = 0x80
|
||
|
cur byte
|
||
|
bytes []byte
|
||
|
)
|
||
|
|
||
|
for _, c := range s {
|
||
|
switch c {
|
||
|
case ' ':
|
||
|
continue
|
||
|
case '1':
|
||
|
cur |= a
|
||
|
case '0':
|
||
|
default:
|
||
|
return nil, errors.New("invalid binary string")
|
||
|
}
|
||
|
|
||
|
a >>= 1
|
||
|
if a == 0 {
|
||
|
bytes = append(bytes, cur)
|
||
|
cur = 0
|
||
|
a = 0x80
|
||
|
}
|
||
|
}
|
||
|
return bytes, nil
|
||
|
}
|