Skip to content

Commit

Permalink
feat: SOF-1254 add temporal priority to TriCaster
Browse files Browse the repository at this point in the history
allows reordering commands that are meant to execte at the same time
  • Loading branch information
ianshade committed Mar 8, 2023
1 parent daa7d9b commit 7133774
Show file tree
Hide file tree
Showing 9 changed files with 484 additions and 340 deletions.
17 changes: 17 additions & 0 deletions packages/timeline-state-resolver-types/src/tricaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ export interface TimelineObjTriCasterBase extends TSRTimelineObjBase {
content: {
deviceType: DeviceType.TRICASTER
type: TimelineContentTypeTriCaster
/**
* Priority used to sort commands that are supposed to execute at the same time
* Default: 0
*/
temporalPriority?: number
} & TimelineDatastoreReferencesContent
}

Expand Down Expand Up @@ -143,6 +148,8 @@ export interface TimelineObjTriCasterME extends TimelineObjTriCasterBase {
type: TimelineContentTypeTriCaster.ME

me: TriCasterMixEffect

temporalPriority?: number
} & TimelineDatastoreReferencesContent
}

Expand All @@ -163,6 +170,8 @@ export interface TimelineObjTriCasterDSK extends TimelineObjTriCasterBase {
type: TimelineContentTypeTriCaster.DSK

keyer: TriCasterKeyer

temporalPriority?: number
} & TimelineDatastoreReferencesContent
}

Expand All @@ -183,6 +192,8 @@ export interface TimelineObjTriCasterInput extends TimelineObjTriCasterBase {
type: TimelineContentTypeTriCaster.INPUT

input: TriCasterInput

temporalPriority?: number
} & TimelineDatastoreReferencesContent
}

Expand All @@ -207,6 +218,8 @@ export interface TimelineObjTriCasterAudioChannel extends TimelineObjTriCasterBa
type: TimelineContentTypeTriCaster.AUDIO_CHANNEL

audioChannel: TriCasterAudioChannel

temporalPriority?: number
} & TimelineDatastoreReferencesContent
}

Expand All @@ -232,6 +245,8 @@ export interface TimelineObjTriCasterMixOutput extends TimelineObjTriCasterBase
* or 'program', 'preview', 'program_clean', 'me_program', 'me_preview'
*/
source: TriCasterMixOutputSource

temporalPriority?: number
} & TimelineDatastoreReferencesContent
}

Expand All @@ -256,6 +271,8 @@ export interface TimelineObjTriCasterMatrixOutput extends TimelineObjTriCasterBa
* or mix outputs ('mixN') e.g. 'mix2'
*/
source: TriCasterMatrixOutputSource

temporalPriority?: number
} & TimelineDatastoreReferencesContent
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ describe('TriCasterShortcutStateConverter.getTriCasterStateFromShortcutState', (
<shortcut_state name="main_b_row_named_input" value="DDR2" type="" sender="unknown"/>
</shortcut_states>`)

expect(state.mixEffects['main'].programInput).toEqual('input7')
expect(state.mixEffects['main'].previewInput).toEqual('ddr2')
expect(state.mixEffects['main'].programInput).toEqual({ value: 'input7' })
expect(state.mixEffects['main'].previewInput).toEqual({ value: 'ddr2' })
})
})

Expand All @@ -38,10 +38,10 @@ describe('TriCasterShortcutStateConverter.getTriCasterStateFromShortcutState', (
<shortcut_state name="main_dsk4_value" value="0" type="double" sender="unknown" />
</shortcut_states>`)

expect(state.mixEffects.main.keyers?.dsk1.onAir).toEqual(false)
expect(state.mixEffects.main.keyers?.dsk2.onAir).toEqual(true)
expect(state.mixEffects.main.keyers?.dsk3.onAir).toEqual(true)
expect(state.mixEffects.main.keyers?.dsk4.onAir).toEqual(false)
expect(state.mixEffects.main.keyers?.dsk1.onAir).toEqual({ value: false })
expect(state.mixEffects.main.keyers?.dsk2.onAir).toEqual({ value: true })
expect(state.mixEffects.main.keyers?.dsk3.onAir).toEqual({ value: true })
expect(state.mixEffects.main.keyers?.dsk4.onAir).toEqual({ value: false })
})

test('sets input', () => {
Expand All @@ -51,7 +51,7 @@ describe('TriCasterShortcutStateConverter.getTriCasterStateFromShortcutState', (
<shortcut_state name="main_dsk3_select_named_input" value="v6" type="" sender="unknown"/>
</shortcut_states>`)

expect(state.mixEffects.main.keyers?.dsk3.input).toEqual('v6')
expect(state.mixEffects.main.keyers?.dsk3.input).toEqual({ value: 'v6' })
})
})

Expand All @@ -63,7 +63,7 @@ describe('TriCasterShortcutStateConverter.getTriCasterStateFromShortcutState', (
<shortcut_state name="v2_a_row_named_input" value="v6" type="" sender="unknown"/>
</shortcut_states>`)

expect(state.mixEffects.v2.layers?.a?.input).toEqual('v6')
expect(state.mixEffects.v2.layers?.a?.input).toEqual({ value: 'v6' })
})
})

Expand All @@ -76,8 +76,8 @@ describe('TriCasterShortcutStateConverter.getTriCasterStateFromShortcutState', (
<shortcut_state name="mix2_output_source" value="me_preview" type="" sender="unknown"/>
</shortcut_states>`)

expect(state.mixOutputs.mix1.source).toEqual('input7')
expect(state.mixOutputs.mix2.source).toEqual('me_preview')
expect(state.mixOutputs.mix1.source).toEqual({ value: 'input7' })
expect(state.mixOutputs.mix2.source).toEqual({ value: 'me_preview' })
})
})

Expand All @@ -90,8 +90,8 @@ describe('TriCasterShortcutStateConverter.getTriCasterStateFromShortcutState', (
<shortcut_state name="out2_crosspoint_source" value="mix2" type="" sender="unknown"/>
</shortcut_states>`)

expect(state.matrixOutputs.out1.source).toEqual('input5')
expect(state.matrixOutputs.out2.source).toEqual('mix2')
expect(state.matrixOutputs.out1.source).toEqual({ value: 'input5' })
expect(state.matrixOutputs.out2.source).toEqual({ value: 'mix2' })
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
RequiredDeep,
TriCasterKeyerState,
TriCasterLayerState,
TriCasterState,
wrapInExtendedState,
} from '../triCasterStateDiffer'
import { literal } from '../../../devices/device'
import { wrapIntoResolvedInstance } from './helpers'
Expand All @@ -29,31 +31,32 @@ function setupTimelineStateConverter() {
})
}

const mockGetDefaultState = (): CompleteTriCasterState => ({
mixEffects: { main: mockGetDefaultMe(), v1: mockGetDefaultMe() }, // pretend we only have mappings for those two
inputs: {
input1: {
videoActAsAlpha: false,
videoSource: undefined,
const mockGetDefaultState = (): CompleteTriCasterState =>
wrapInExtendedState<TriCasterState>({
mixEffects: { main: mockGetDefaultMe(), v1: mockGetDefaultMe() }, // pretend we only have mappings for those two
inputs: {
input1: {
videoActAsAlpha: false,
videoSource: undefined,
},
input2: {
videoActAsAlpha: false,
videoSource: undefined,
},
},
input2: {
videoActAsAlpha: false,
videoSource: undefined,
// @ts-ignore for now
audioChannels: {},
isRecording: false,
isStreaming: false,
mixOutputs: {
mix1: { source: 'program' },
mix2: { source: 'program' },
},
},
// @ts-ignore for now
audioChannels: {},
isRecording: false,
isStreaming: false,
mixOutputs: {
mix1: { source: 'program' },
mix2: { source: 'program' },
},
matrixOutputs: {
out1: { source: 'mix1' },
out2: { source: 'mix1' },
},
})
matrixOutputs: {
out1: { source: 'mix1' },
out2: { source: 'mix1' },
},
})

const mockGetDefaultMe = (): CompleteTriCasterMixEffectState => ({
programInput: 'black',
Expand Down Expand Up @@ -113,7 +116,7 @@ describe('TimelineStateConverter.getTriCasterStateFromTimelineState', () => {
tc_me0_1: wrapIntoResolvedInstance<TimelineObjTriCasterME>({
layer: 'tc_me0_1',
enable: { while: '1' },
id: 't0',
id: 't1',
content: {
deviceType: DeviceType.TRICASTER,
type: TimelineContentTypeTriCaster.ME,
Expand Down Expand Up @@ -162,34 +165,35 @@ describe('TimelineStateConverter.getTriCasterStateFromTimelineState', () => {
)

const expectedState = mockGetDefaultState()
expectedState.mixEffects.main.programInput = 'input2'
expectedState.mixEffects.main.previewInput = 'input3'
expectedState.mixEffects.main.transitionEffect = 5
expectedState.mixEffects.main.transitionDuration = 20
expectedState.mixEffects.v1.keyers.dsk2.input = 'input5'
expectedState.mixEffects.v1.keyers.dsk2.onAir = true
expectedState.mixEffects.main.programInput = { value: 'input2', timelineObjectId: 't0' }
expectedState.mixEffects.main.previewInput = { value: 'input3', timelineObjectId: 't0' }
expectedState.mixEffects.main.transitionEffect = { value: 5, timelineObjectId: 't0' }
expectedState.mixEffects.main.transitionDuration = { value: 20, timelineObjectId: 't0' }
expectedState.mixEffects.v1.keyers.dsk2.input = { value: 'input5', timelineObjectId: 't1' }
expectedState.mixEffects.v1.keyers.dsk2.onAir = { value: true, timelineObjectId: 't1' }
// @ts-ignore
expectedState.mixEffects.v1.layers!.b = {
input: 'ddr3',
input: { value: 'ddr3', timelineObjectId: 't1' },
position: {
x: 2,
y: -1.5,
x: { value: 2, timelineObjectId: 't1' },
y: { value: -1.5, timelineObjectId: 't1' },
},
crop: {
left: 5,
right: 10,
up: 1.1111,
down: 99.9,
left: { value: 5, timelineObjectId: 't1' },
right: { value: 10, timelineObjectId: 't1' },
up: { value: 1.1111, timelineObjectId: 't1' },
down: { value: 99.9, timelineObjectId: 't1' },
},
scale: { x: 200, y: 90 },
scale: { x: { value: 200, timelineObjectId: 't1' }, y: { value: 90, timelineObjectId: 't1' } },
rotation: {
x: 1,
y: 2,
z: 3,
x: { value: 1, timelineObjectId: 't1' },
y: { value: 2, timelineObjectId: 't1' },
z: { value: 3, timelineObjectId: 't1' },
},
feather: 67.67,
positioningAndCropEnabled: true,
feather: { value: 67.67, timelineObjectId: 't1' },
positioningAndCropEnabled: { value: true, timelineObjectId: 't1' },
}
expectedState.mixEffects.v1.isInEffectMode = true
expectedState.mixEffects.v1.isInEffectMode.value = true

expect(convertedState).toEqual(expectedState)
})
Expand Down Expand Up @@ -225,7 +229,7 @@ describe('TimelineStateConverter.getTriCasterStateFromTimelineState', () => {
)

const expectedState = mockGetDefaultState()
expectedState.matrixOutputs.out2.source = 'input5'
expectedState.matrixOutputs.out2.source = { value: 'input5', timelineObjectId: 't0' }

expect(convertedState).toEqual(expectedState)
})
Expand Down Expand Up @@ -261,7 +265,7 @@ describe('TimelineStateConverter.getTriCasterStateFromTimelineState', () => {
)

const expectedState = mockGetDefaultState()
expectedState.mixOutputs.mix2.source = 'me_program'
expectedState.mixOutputs.mix2.source = { value: 'me_program', timelineObjectId: 't0' }

expect(convertedState).toEqual(expectedState)
})
Expand Down Expand Up @@ -301,8 +305,8 @@ describe('TimelineStateConverter.getTriCasterStateFromTimelineState', () => {

const expectedState = mockGetDefaultState()
expectedState.inputs.input2 = {
videoSource: 'Input 10',
videoActAsAlpha: true,
videoSource: { value: 'Input 10', timelineObjectId: 't0' },
videoActAsAlpha: { value: true, timelineObjectId: 't0' },
}

expect(convertedState).toEqual(expectedState)
Expand Down
Loading

0 comments on commit 7133774

Please sign in to comment.