-
Notifications
You must be signed in to change notification settings - Fork 51
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
Solve the the issue of non-DVB transport stream(TS) which using the PID, 0x10~0x1F, as the PIDs of the video/audio streams of program #54
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ import ( | |
func TestParseData(t *testing.T) { | ||
// Init | ||
pm := newProgramMap() | ||
esm := newElementaryStreamMap() | ||
ps := []*Packet{} | ||
|
||
// Custom parser | ||
|
@@ -20,13 +21,13 @@ func TestParseData(t *testing.T) { | |
skip = true | ||
return | ||
} | ||
ds, err := parseData(ps, c, pm) | ||
ds, err := parseData(ps, c, pm, esm) | ||
assert.NoError(t, err) | ||
assert.Equal(t, cds, ds) | ||
|
||
// Do nothing for CAT | ||
ps = []*Packet{{Header: PacketHeader{PID: PIDCAT}}} | ||
ds, err = parseData(ps, nil, pm) | ||
ds, err = parseData(ps, nil, pm, esm) | ||
assert.NoError(t, err) | ||
assert.Empty(t, ds) | ||
|
||
|
@@ -42,7 +43,7 @@ func TestParseData(t *testing.T) { | |
Payload: p[33:], | ||
}, | ||
} | ||
ds, err = parseData(ps, nil, pm) | ||
ds, err = parseData(ps, nil, pm, esm) | ||
assert.NoError(t, err) | ||
assert.Equal(t, []*DemuxerData{ | ||
{ | ||
|
@@ -64,7 +65,7 @@ func TestParseData(t *testing.T) { | |
Payload: p[33:], | ||
}, | ||
} | ||
ds, err = parseData(ps, nil, pm) | ||
ds, err = parseData(ps, nil, pm, esm) | ||
assert.NoError(t, err) | ||
assert.Equal(t, psi.toData( | ||
&Packet{Header: ps[0].Header, AdaptationField: ps[0].AdaptationField}, | ||
|
@@ -74,15 +75,16 @@ func TestParseData(t *testing.T) { | |
|
||
func TestIsPSIPayload(t *testing.T) { | ||
pm := newProgramMap() | ||
esm := newElementaryStreamMap() | ||
var pids []int | ||
for i := 0; i <= 255; i++ { | ||
if isPSIPayload(uint16(i), pm) { | ||
if isPSIPayload(uint16(i), pm, esm) { | ||
pids = append(pids, i) | ||
} | ||
} | ||
assert.Equal(t, []int{0, 16, 17, 18, 19, 20, 30, 31}, pids) | ||
pm.setUnlocked(uint16(1), uint16(0)) | ||
assert.True(t, isPSIPayload(uint16(1), pm)) | ||
assert.True(t, isPSIPayload(uint16(1), pm, esm)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add a test using |
||
} | ||
|
||
func TestIsPESPayload(t *testing.T) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ type Demuxer struct { | |
packetBuffer *packetBuffer | ||
packetPool *packetPool | ||
programMap *programMap | ||
streamMap *elementaryStreamMap | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you order fields alphabetically? |
||
r io.Reader | ||
} | ||
|
||
|
@@ -52,6 +53,7 @@ func NewDemuxer(ctx context.Context, r io.Reader, opts ...func(*Demuxer)) (d *De | |
ctx: ctx, | ||
l: astikit.AdaptStdLogger(nil), | ||
programMap: newProgramMap(), | ||
streamMap: newElementaryStreamMap(), | ||
r: r, | ||
} | ||
d.packetPool = newPacketPool(d.programMap) | ||
|
@@ -145,7 +147,7 @@ func (dmx *Demuxer) NextData() (d *DemuxerData, err error) { | |
|
||
// Parse data | ||
var errParseData error | ||
if ds, errParseData = parseData(ps, dmx.optPacketsParser, dmx.programMap); errParseData != nil { | ||
if ds, errParseData = parseData(ps, dmx.optPacketsParser, dmx.programMap, dmx.streamMap); errParseData != nil { | ||
// Log error as there may be some incomplete data here | ||
// We still want to try to parse all packets, in case final data is complete | ||
dmx.l.Error(fmt.Errorf("astits: parsing data failed: %w", errParseData)) | ||
|
@@ -170,7 +172,7 @@ func (dmx *Demuxer) NextData() (d *DemuxerData, err error) { | |
} | ||
|
||
// Parse data | ||
if ds, err = parseData(ps, dmx.optPacketsParser, dmx.programMap); err != nil { | ||
if ds, err = parseData(ps, dmx.optPacketsParser, dmx.programMap, dmx.streamMap); err != nil { | ||
err = fmt.Errorf("astits: building new data failed: %w", err) | ||
return | ||
} | ||
|
@@ -199,6 +201,11 @@ func (dmx *Demuxer) updateData(ds []*DemuxerData) (d *DemuxerData) { | |
} | ||
} | ||
} | ||
if v.PMT != nil { | ||
for _, es := range v.PMT.ElementaryStreams { | ||
dmx.streamMap.setLocked(es.ElementaryPID, v.PMT.ProgramNumber) | ||
} | ||
} | ||
} | ||
} | ||
return | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package astits | ||
|
||
// elementaryStreamMap represents an elementary stream ids map | ||
type elementaryStreamMap struct { | ||
// We use map[uint32] instead map[uint16] as go runtime provide optimized hash functions for (u)int32/64 keys | ||
es map[uint32]uint16 // map[StreamID]ProgramNumber | ||
} | ||
|
||
// newElementaryStreamMap creates a new elementary stream ids map | ||
func newElementaryStreamMap() *elementaryStreamMap { | ||
return &elementaryStreamMap{ | ||
es: make(map[uint32]uint16), | ||
} | ||
} | ||
|
||
// setLocked sets a new stream id to the elementary stream | ||
func (m elementaryStreamMap) setLocked(pid, number uint16) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you rename The idea is to let the developer know the function is not locking any mutex while manipulating the map which is really unsafe. |
||
m.es[uint32(pid)] = number | ||
} | ||
|
||
// existsLocked checks whether the stream with this pid exists | ||
func (m elementaryStreamMap) existsLocked(pid uint16) (ok bool) { | ||
_, ok = m.es[uint32(pid)] | ||
return | ||
} | ||
|
||
func (m elementaryStreamMap) unsetLocked(pid uint16) { | ||
delete(m.es, uint32(pid)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package astits | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestElementaryStreamMap(t *testing.T) { | ||
esm := newElementaryStreamMap() | ||
assert.False(t, esm.existsLocked(0x16)) | ||
esm.setLocked(0x16, 1) | ||
assert.True(t, esm.existsLocked(0x16)) | ||
esm.unsetLocked(0x16) | ||
assert.False(t, esm.existsLocked(0x16)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a test using
esm.setUnlocked()
like it was done withpm.setUnlocked(uint16(256), uint16(1))
above?