mirror of https://bitbucket.org/ausocean/av.git
container/mts: added commenting to SegmentForMeta and accompanying testing
This commit is contained in:
parent
3eab25e18b
commit
74992aee19
|
@ -443,19 +443,25 @@ func TrimToMetaRange(d []byte, key, from, to string) ([]byte, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SegmentForMeta returns segments of MTS slice d that correspond to a value of
|
||||||
|
// meta for key and val. Therefore, any sequence of packets corresponding to
|
||||||
|
// key and val will be appended to the returned [][]byte.
|
||||||
func SegmentForMeta(d []byte, key, val string) ([][]byte, error) {
|
func SegmentForMeta(d []byte, key, val string) ([][]byte, error) {
|
||||||
var (
|
var (
|
||||||
pkt packet.Packet
|
pkt packet.Packet // We copy data to this so that we can use comcast gots stuff.
|
||||||
segmenting bool
|
segmenting bool // If true we are currently in a segment corresponsing to given meta.
|
||||||
res [][]byte
|
res [][]byte // The resultant [][]byte holding the segments.
|
||||||
start int
|
start int // The start index of the current segment.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Go through packets.
|
||||||
for i := 0; i < len(d); i += PacketSize {
|
for i := 0; i < len(d); i += PacketSize {
|
||||||
copy(pkt[:], d[i:i+PacketSize])
|
copy(pkt[:], d[i:i+PacketSize])
|
||||||
if pkt.PID() == PmtPid {
|
if pkt.PID() == PmtPid {
|
||||||
_meta, err := ExtractMeta(pkt[:])
|
_meta, err := ExtractMeta(pkt[:])
|
||||||
switch err {
|
switch err {
|
||||||
|
// If there's no meta or a problem with meta, we consider this the end
|
||||||
|
// of the segment.
|
||||||
case errNoMeta, meta.ErrUnexpectedMetaFormat:
|
case errNoMeta, meta.ErrUnexpectedMetaFormat:
|
||||||
if segmenting {
|
if segmenting {
|
||||||
res = append(res, d[start:i])
|
res = append(res, d[start:i])
|
||||||
|
@ -467,6 +473,9 @@ func SegmentForMeta(d []byte, key, val string) ([][]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we've got the meta of interest in the PMT and we're not segmenting
|
||||||
|
// then start segmenting. If we don't have the meta of interest in the PMT
|
||||||
|
// and we are segmenting then we want to stop and append the segment to result.
|
||||||
if _meta[key] == val && !segmenting {
|
if _meta[key] == val && !segmenting {
|
||||||
start = i
|
start = i
|
||||||
segmenting = true
|
segmenting = true
|
||||||
|
@ -477,6 +486,8 @@ func SegmentForMeta(d []byte, key, val string) ([][]byte, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We've reached the end of the entire MTS clip so if we're segmenting we need
|
||||||
|
// to append current segment to res.
|
||||||
if segmenting {
|
if segmenting {
|
||||||
res = append(res, d[start:len(d)])
|
res = append(res, d[start:len(d)])
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,18 +336,20 @@ func TestTrimToMetaRange(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSegmentForMeta checks that SegmentForMeta can correctly segment some MTS
|
||||||
|
// data based on a given meta key and value.
|
||||||
func TestSegmentForMeta(t *testing.T) {
|
func TestSegmentForMeta(t *testing.T) {
|
||||||
Meta = meta.New()
|
Meta = meta.New()
|
||||||
|
|
||||||
const (
|
const (
|
||||||
nPSI = 10
|
nPSI = 10 // The number of PSI pairs to write.
|
||||||
key = "n"
|
key = "n" // The meta key we will work with.
|
||||||
val = "*"
|
val = "*" // This is the meta value we will look for.
|
||||||
)
|
)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
metaVals [nPSI]string
|
metaVals [nPSI]string // This represents the meta value for meta pairs (PAT and PMT)
|
||||||
expectIdxs []rng
|
expectIdxs []rng // This gives the expect index ranges for the segments.
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
metaVals: [nPSI]string{"1", "2", val, val, val, "3", val, val, "4", "4"},
|
metaVals: [nPSI]string{"1", "2", val, val, val, "3", val, val, "4", "4"},
|
||||||
|
@ -379,7 +381,10 @@ func TestSegmentForMeta(t *testing.T) {
|
||||||
var clip bytes.Buffer
|
var clip bytes.Buffer
|
||||||
|
|
||||||
for testn, test := range tests {
|
for testn, test := range tests {
|
||||||
|
// We want a clean buffer for each new test, so reset.
|
||||||
clip.Reset()
|
clip.Reset()
|
||||||
|
|
||||||
|
// Add meta and write PSI to clip.
|
||||||
for i := 0; i < nPSI; i++ {
|
for i := 0; i < nPSI; i++ {
|
||||||
if test.metaVals[i] != "" {
|
if test.metaVals[i] != "" {
|
||||||
Meta.Add(key, test.metaVals[i])
|
Meta.Add(key, test.metaVals[i])
|
||||||
|
@ -391,26 +396,36 @@ func TestSegmentForMeta(t *testing.T) {
|
||||||
t.Fatalf("did not expect to get error writing PSI, error: %v", err)
|
t.Fatalf("did not expect to get error writing PSI, error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now we get the expected segments using the index ranges from the test.
|
||||||
var want [][]byte
|
var want [][]byte
|
||||||
for _, idxs := range test.expectIdxs {
|
for _, idxs := range test.expectIdxs {
|
||||||
want = append(want, clip.Bytes()[idxs.start:idxs.end])
|
want = append(want, clip.Bytes()[idxs.start:idxs.end])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now use the function we're testing to get the segments.
|
||||||
got, err := SegmentForMeta(clip.Bytes(), key, val)
|
got, err := SegmentForMeta(clip.Bytes(), key, val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that segments are OK.
|
||||||
if !reflect.DeepEqual(want, got) {
|
if !reflect.DeepEqual(want, got) {
|
||||||
t.Errorf("did not get expected result for test %v\nGot: %v\nWant: %v\n", testn, got, want)
|
t.Errorf("did not get expected result for test %v\nGot: %v\nWant: %v\n", testn, got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rng describes an index range and is used by TestSegmentForMeta.
|
||||||
type rng struct {
|
type rng struct {
|
||||||
start int
|
start int
|
||||||
end int
|
end int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scale takes a PSI index (i.e. first PSI is 0, next is 1) and modifies to be
|
||||||
|
// the index of the first byte of the PSI pair (PAT and PMT) in the byte stream.
|
||||||
|
// This assumes there are only PSI written consequitively, and is used by
|
||||||
|
// TestSegmentForMeta.
|
||||||
func scale(x, y int) rng {
|
func scale(x, y int) rng {
|
||||||
return rng{
|
return rng{
|
||||||
((x * 2) + 1) * PacketSize,
|
((x * 2) + 1) * PacketSize,
|
||||||
|
|
Loading…
Reference in New Issue