streaming

Media streaming and broadcast systems in Go
Log | Files | Refs | README | LICENSE

codec_test.go (3258B)


      1 package mpegts
      2 
      3 import (
      4 	"bytes"
      5 	"crypto/md5"
      6 	"errors"
      7 	"io"
      8 	"os"
      9 	"testing"
     10 )
     11 
     12 func TestDecode(t *testing.T) {
     13 	f, err := os.Open("testdata/193039199_mp4_h264_aac_hq_7.ts")
     14 	if err != nil {
     15 		t.Fatal(err)
     16 	}
     17 	defer f.Close()
     18 	var i int
     19 	for {
     20 		i++
     21 		var in [188]byte
     22 		n, err := f.Read(in[:])
     23 		if errors.Is(err, io.EOF) {
     24 			break
     25 		} else if n != PacketSize {
     26 			t.Fatalf("short read: read %d bytes", n)
     27 		} else if err != nil {
     28 			t.Fatalf("read packet: %v", err)
     29 		}
     30 		p, err := Decode(bytes.NewReader(in[:]))
     31 		if err != nil {
     32 			t.Fatalf("decode packet: %v", err)
     33 		}
     34 
     35 		buf := &bytes.Buffer{}
     36 		if err := Encode(buf, p); err != nil {
     37 			t.Logf("%+v", p)
     38 			if p.Adaptation != nil {
     39 				t.Logf("%+v", p.Adaptation)
     40 			}
     41 			if p.PES != nil {
     42 				t.Logf("%+v", p.PES)
     43 				if p.PES.Header != nil {
     44 					t.Logf("PES header: %+v", p.PES.Header)
     45 				}
     46 			}
     47 			t.Fatalf("encode packet %d: %v", i, err)
     48 		}
     49 		var out [188]byte
     50 		copy(out[:], buf.Bytes())
     51 
     52 		if in != out {
     53 			t.Errorf("packet %d: encoded and source bytes differ", i)
     54 			t.Logf("%+v", p)
     55 			if p.Adaptation != nil {
     56 				t.Logf("%+v", p.Adaptation)
     57 			}
     58 			if p.PES != nil {
     59 				t.Logf("%+v", p.PES)
     60 				if p.PES.Header != nil {
     61 					t.Logf("PES header: %+v", p.PES.Header)
     62 				}
     63 			}
     64 			for i := range in {
     65 				if in[i] != out[i] {
     66 					t.Errorf("byte %d: source %08b, encoded %08b", i, in[i], out[i])
     67 					t.Errorf("byte %d: source %#x, encoded %#x", i, in[i], out[i])
     68 				}
     69 			}
     70 		}
     71 	}
     72 }
     73 
     74 func TestBadData(t *testing.T) {
     75 	m := map[string][]byte{
     76 		"garbage":         []byte("0123456789"),
     77 		"only sync bytes": bytes.Repeat([]byte{Sync}, PacketSize),
     78 	}
     79 	for name, in := range m {
     80 		t.Run(name, func(t *testing.T) {
     81 			var p Packet
     82 			if err := Unmarshal(in, &p); err == nil {
     83 				t.Errorf("Unmarshal(%s): nil error", string(in))
     84 			}
     85 		})
     86 	}
     87 }
     88 
     89 func TestScanner(t *testing.T) {
     90 	name := "testdata/193039199_mp4_h264_aac_hq_7.ts"
     91 	data, err := os.ReadFile(name)
     92 	if err != nil {
     93 		t.Fatal(err)
     94 	}
     95 	sum := md5.Sum(data)
     96 
     97 	f, err := os.Open(name)
     98 	if err != nil {
     99 		t.Fatal(err)
    100 	}
    101 	defer f.Close()
    102 	buf := &bytes.Buffer{}
    103 	sc := NewScanner(f)
    104 	var i int
    105 	for sc.Scan() {
    106 		i++
    107 		p := sc.Packet()
    108 		if err := Encode(buf, p); err != nil {
    109 			t.Fatalf("packet %d: encode: %v", i, err)
    110 		}
    111 	}
    112 	if sc.Err() != nil {
    113 		t.Fatalf("scan: %v", sc.Err())
    114 	}
    115 	got := md5.Sum(buf.Bytes())
    116 	if got != sum {
    117 		t.Errorf("re-encoded stream differs from source: got checksum %x, want %x", got, sum)
    118 	}
    119 }
    120 
    121 func TestPCR(t *testing.T) {
    122 	var tests = []struct {
    123 		name    string
    124 		encoded [6]byte
    125 		want    PCR
    126 	}{
    127 		{
    128 			"zero",
    129 			[6]byte{0, 0, 0, 0, 0b01111110, 0}, // 6 reserved bits toggled
    130 			PCR{},
    131 		},
    132 		{
    133 			"max base", // 2^33 - 1
    134 			[6]byte{0xff, 0xff, 0xff, 0xff, 0xfe, 0x00},
    135 			PCR{8589934591, 0},
    136 		},
    137 		{
    138 			"max extension", // 2^9 - 1
    139 			[6]byte{0, 0, 0, 0, 0x7f, 0xff},
    140 			PCR{0, 511},
    141 		},
    142 	}
    143 	for _, tt := range tests {
    144 		t.Run(tt.name, func(t *testing.T) {
    145 			pcr := parsePCR(tt.encoded)
    146 			if pcr != tt.want {
    147 				t.Errorf("parsePCR(%v) = %v, want %v", tt.encoded, pcr, tt.want)
    148 			}
    149 
    150 			var a [6]byte
    151 			if err := putPCR(a[:], &pcr); err != nil {
    152 				t.Fatalf("put PCR: %v", err)
    153 			}
    154 			if a != tt.encoded {
    155 				t.Errorf("re-encoded pcr is %v, want %v", a, tt.encoded)
    156 			}
    157 		})
    158 	}
    159 }