container/mts: added commenting to SegmentForMeta and accompanying testing

This commit is contained in:
Saxon 2019-06-17 16:34:22 +09:30
parent 3eab25e18b
commit 74992aee19
2 changed files with 35 additions and 9 deletions

View File

@ -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)])
} }

View File

@ -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,