Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PSI: parse multiple sections correctly #27

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions data_psi.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ func parsePSIData(i *astikit.BytesIterator) (d *PSIData, err error) {
err = fmt.Errorf("astits: parsing PSI table failed: %w", err)
return
}
if stop {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you just replace this by an else if?

break
}
d.Sections = append(d.Sections, s)
}
return
Expand Down Expand Up @@ -199,8 +202,7 @@ func parseCRC32(i *astikit.BytesIterator) (c uint32, err error) {

// shouldStopPSIParsing checks whether the PSI parsing should be stopped
func shouldStopPSIParsing(tableID PSITableID) bool {
return tableID == PSITableIDNull ||
tableID.isUnknown()
return tableID == PSITableIDNull
}

// parsePSISectionHeader parses a PSI section header
Expand Down Expand Up @@ -241,7 +243,7 @@ func parsePSISectionHeader(i *astikit.BytesIterator) (h *PSISectionHeader, offse
h.PrivateBit = bs[0]&0x40 > 0

// Section length
h.SectionLength = uint16(bs[0]&0xf)<<8 | uint16(bs[1])
h.SectionLength = uint16(bs[0]&3)<<8 | uint16(bs[1])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that &3 is not correct here, it should be 0xf, since the specification says that section length is 12 bits long.

Screenshot 2021-04-07 at 16 01 37

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: I always use this copy of spec: http://www.itu.int/rec/T-REC-H.222.0-201410-S/en

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On page 50 it says the section_length is only 10 bits:

section_length – This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the number of bytes of the section, starting immediately following the section_length field, and including the CRC. The value in this field shall not exceed 1021 (0x3FD).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, I missed that one. Can you please fix this one in muxer as well?


// Offsets
offsetSectionsStart = i.Offset()
Expand Down
31 changes: 31 additions & 0 deletions data_psi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@ package astits

import (
"bytes"
"encoding/hex"
"strings"
"testing"

"github.com/asticode/go-astikit"
"github.com/stretchr/testify/assert"
)

func hexToBytes(in string) []byte {
o, err := hex.DecodeString(strings.ReplaceAll(in, "\n", ""))
if err != nil {
panic(err)
}
return o
}

var psi = &PSIData{
PointerField: 4,
Sections: []*PSISection{
Expand Down Expand Up @@ -356,6 +366,27 @@ var psiDataTestCases = []psiDataTestCase{
},
}

func TestParsePSIDataPMTMultipleSections(t *testing.T) {
pmt := hexToBytes(`00C0001500000100FF000000
000000010000000000038D646B02B07B
0001C90000EF9BF02109044749E10B05
04474139348713C1010100F30D01656E
670100000554562D504702EF9BF00E11
01FF1006C0BD62C0080006010281EF9C
F018050441432D33810A083805FF0F01
BF656E670A04656E670081EF9DF01805
0441432D33810A082885FF0001BF7370
610A0473706100082F08E3FFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFF`)
d, err := parsePSIData(astikit.NewBytesIterator(pmt))
assert.NoError(t, err)
assert.NotNil(t, d)
assert.Len(t, d.Sections, 2)
assert.Equal(t, PSITableID(0xc0), d.Sections[0].Header.TableID)
assert.Equal(t, PSITableID(0x02), d.Sections[1].Header.TableID)
}

func TestWritePSIData(t *testing.T) {
for _, tc := range psiDataTestCases {
t.Run(tc.name, func(t *testing.T) {
Expand Down
31 changes: 31 additions & 0 deletions demuxer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,37 @@ func TestDemuxerNextData(t *testing.T) {
assert.EqualError(t, err, ErrNoMorePackets.Error())
}

func TestDemuxerNextDataPMTComplex(t *testing.T) {
// complex pmt with two tables (0xc0 and 0x2) split across two packets
pmt := hexToBytes(`47403b1e00c0001500000100610000000000000100000000
0035e3e2d702b0b20001c50000eefdf01809044749e10b05
0441432d330504454143330504435545491beefdf0102a02
7e1f9700e9080c001f418507d04181eefef00f810706380f
ff1f003f0a04656e670081eefff00f8107061003ff1f003f
0a047370610086ef00f00f8a01009700e9080c001f418507
d041c0ef01f012050445545631a100e9080c001f418507d0
41c0ef02f013050445545631a20100e9080c001f47003b1f
418507d041c0ef03f008bf06496e76696469a5cff3afffff
ffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffff`)
r := bytes.NewReader(pmt)
assert.Equal(t, 188*2, r.Len())

dmx := NewDemuxer(context.Background(), r, DemuxerOptPacketSize(188))
dmx.programMap.set(59, 1)

d, err := dmx.NextData()
assert.NoError(t, err)
assert.NotNil(t, d)
assert.Equal(t, uint16(59), d.FirstPacket.Header.PID)
assert.NotNil(t, d.PMT)
}

func TestDemuxerRewind(t *testing.T) {
r := bytes.NewReader([]byte("content"))
dmx := NewDemuxer(context.Background(), r)
Expand Down