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"},
|
||||
expectIdxs: []rng{
|
||||
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
|
||||
}
|
||||
|
||||
// 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