mirror of https://bitbucket.org/ausocean/av.git
container/mts: added Clip.SegmentForMeta and accompanying testing.
Added a function to segment a Clip into sub Clips that have a consistent meta key and value. Also added testing for this method.
This commit is contained in:
parent
74992aee19
commit
b42510ae22
|
@ -362,7 +362,7 @@ func TestSegmentForMeta(t *testing.T) {
|
||||||
metaVals: [nPSI]string{"1", "2", val, val, val, "", "3", val, val, "4"},
|
metaVals: [nPSI]string{"1", "2", val, val, val, "", "3", val, val, "4"},
|
||||||
expectIdxs: []rng{
|
expectIdxs: []rng{
|
||||||
scale(2, 5),
|
scale(2, 5),
|
||||||
scale(2, 5),
|
scale(7, 9),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -226,3 +226,56 @@ func (c *Clip) TrimToMetaRange(key, from, to string) (*Clip, error) {
|
||||||
}
|
}
|
||||||
return nil, errMetaLowerBound
|
return nil, errMetaLowerBound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SegmentForMeta segments sequences of frames within c possesing meta described
|
||||||
|
// by key and val and are appended to a []Clip which is subsequently returned.
|
||||||
|
func (c *Clip) SegmentForMeta(key, val string) []Clip {
|
||||||
|
var (
|
||||||
|
segmenting bool // If true we are currently in a segment corresponsing to given meta.
|
||||||
|
res []Clip // The resultant [][]Clip holding the segments.
|
||||||
|
start int // The start index of the current segment.
|
||||||
|
)
|
||||||
|
|
||||||
|
// Go through frames of clip.
|
||||||
|
for i, frame := range c.frames {
|
||||||
|
// If there is no meta (meta = nil) and we are segmenting, then append the
|
||||||
|
// current segment to res.
|
||||||
|
if frame.Meta == nil {
|
||||||
|
if segmenting {
|
||||||
|
res = appendSegment(res, c, start, i)
|
||||||
|
segmenting = false
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we've got the meta of interest in current frame and we're not
|
||||||
|
// segmenting, set this i as start and set segmenting true. If we don't
|
||||||
|
// have the meta of interest and we are segmenting then we
|
||||||
|
// want to stop and append the segment to res.
|
||||||
|
if frame.Meta[key] == val && !segmenting {
|
||||||
|
start = i
|
||||||
|
segmenting = true
|
||||||
|
} else if frame.Meta[key] != val && segmenting {
|
||||||
|
res = appendSegment(res, c, start, i)
|
||||||
|
segmenting = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We've reached the end of the entire clip so if we're segmenting we need
|
||||||
|
// to append current segment to res.
|
||||||
|
if segmenting {
|
||||||
|
res = appendSegment(res, c, start, len(c.frames))
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// appendSegment is a helper function used by Clip.SegmentForMeta to append a
|
||||||
|
// clip to a []Clip.
|
||||||
|
func appendSegment(segs []Clip, c *Clip, start, end int) []Clip {
|
||||||
|
return append(segs, Clip{
|
||||||
|
frames: c.frames[start:end],
|
||||||
|
backing: c.backing[c.frames[start].idx : c.frames[end-1].idx+len(c.frames[end-1].Media)],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -399,3 +399,77 @@ func TestClipTrimToMetaRange(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestClipSegmentForMeta checks that Clip.SegmentForMeta correctly returns
|
||||||
|
// segments from a clip with consistent meta defined by a key and value.
|
||||||
|
func TestClipSegmentForMeta(t *testing.T) {
|
||||||
|
const (
|
||||||
|
nFrames = 10 // The number of test frames we want to create.
|
||||||
|
fSize = 3 // The size of the frame media.
|
||||||
|
key = "n" // Meta key we will use.
|
||||||
|
val = "*" // The meta val of interest.
|
||||||
|
)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
metaVals []string // These will be the meta vals each frame has.
|
||||||
|
fIndices []rng // These are the indices of the segments of interest.
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
metaVals: []string{"1", "2", "*", "*", "*", "3", "*", "*", "4", "5"},
|
||||||
|
fIndices: []rng{{2, 5}, {6, 8}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
metaVals: []string{"1", "2", "*", "*", "*", "", "*", "*", "4", "5"},
|
||||||
|
fIndices: []rng{{2, 5}, {6, 8}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
metaVals: []string{"1", "2", "*", "*", "*", "3", "4", "5", "*", "*"},
|
||||||
|
fIndices: []rng{{2, 5}, {8, nFrames}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
metaVals: []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"},
|
||||||
|
fIndices: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the tests.
|
||||||
|
for testn, test := range tests {
|
||||||
|
clip := &Clip{}
|
||||||
|
|
||||||
|
// Generate test frames.
|
||||||
|
for i := 0; i < nFrames; i++ {
|
||||||
|
clip.backing = append(clip.backing, []byte{byte(i), byte(i), byte(i)}...)
|
||||||
|
clip.frames = append(
|
||||||
|
clip.frames,
|
||||||
|
Frame{
|
||||||
|
Media: clip.backing[i*fSize : (i+1)*fSize],
|
||||||
|
idx: i * fSize,
|
||||||
|
Meta: map[string]string{
|
||||||
|
key: test.metaVals[i],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use function we're testing to get segments.
|
||||||
|
got := clip.SegmentForMeta(key, val)
|
||||||
|
|
||||||
|
// Now get expected segments using indices defined in the test.
|
||||||
|
var want []Clip
|
||||||
|
for _, indices := range test.fIndices {
|
||||||
|
// Calculate the indices for the backing array from the original clip.
|
||||||
|
backStart := clip.frames[indices.start].idx
|
||||||
|
backEnd := clip.frames[indices.end-1].idx + len(clip.frames[indices.end-1].Media)
|
||||||
|
|
||||||
|
// Use calculated indices to create Clip for current expected segment.
|
||||||
|
want = append(want, Clip{
|
||||||
|
frames: clip.frames[indices.start:indices.end],
|
||||||
|
backing: clip.backing[backStart:backEnd],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("did not get expected result for test %v\nGot: %v\nWant: %v\n", testn, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue