mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-11-13 15:27:21 +00:00
[client] lgmp: test same-generation audio restart
Queue playback STOP, START, and DATA for the same wire generation. Verify that the client creates a fresh local generation and delivers the first restarted packet.
This commit is contained in:
@@ -811,6 +811,89 @@ static bool testRetiredClaim(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool testPlaybackRestartSameGeneration(void)
|
||||||
|
{
|
||||||
|
struct Fixture fixture;
|
||||||
|
CHECK(fixtureInit(&fixture));
|
||||||
|
CHECK(beginClaim(&fixture, false));
|
||||||
|
CHECK(createStreams(&fixture));
|
||||||
|
CHECK(bindStreams(&fixture));
|
||||||
|
CHECK(deliverBoundResponse(&fixture, &fixture.claim, true));
|
||||||
|
|
||||||
|
KVMFRAudioMessage message;
|
||||||
|
uint8_t payload[KVMFR_AUDIO_PCM_BYTES];
|
||||||
|
CHECK(readC2HType(&fixture, KVMFR_AUDIO_MESSAGE_KEEPALIVE,
|
||||||
|
&message, payload, WAIT_MS));
|
||||||
|
|
||||||
|
const uint64_t wireGeneration = UINT64_C(0x300000001);
|
||||||
|
const KVMFRAudioFormat format = makeFormat(
|
||||||
|
KVMFR_AUDIO_CHANNEL_FRONT_LEFT, KVMFR_AUDIO_SAMPLE_S24_LE);
|
||||||
|
CHECK(sendH2C(&fixture, KVMFR_AUDIO_MESSAGE_PLAYBACK_START,
|
||||||
|
wireGeneration, 0, 0, 0, 0, 0,
|
||||||
|
&format, sizeof(format)));
|
||||||
|
CHECK(sendStatus(&fixture, true, KVMFR_AUDIO_CAP_PLAYBACK,
|
||||||
|
wireGeneration, &format, 0, NULL));
|
||||||
|
CHECK(waitCount(&fixture, &fixture.trace.statusCount, 2, WAIT_MS));
|
||||||
|
CHECK(fixture.ops->attach(fixture.audio, &eventOps, &fixture.trace));
|
||||||
|
CHECK(waitCount(&fixture, &fixture.trace.playStartCount, 1, WAIT_MS));
|
||||||
|
|
||||||
|
pthread_mutex_lock(&fixture.trace.mutex);
|
||||||
|
const uint32_t oldLocalGeneration = fixture.trace.playGeneration;
|
||||||
|
const unsigned eventBefore = fixture.trace.eventCount;
|
||||||
|
pthread_mutex_unlock(&fixture.trace.mutex);
|
||||||
|
CHECK(oldLocalGeneration != 0);
|
||||||
|
|
||||||
|
uint8_t pcm[12];
|
||||||
|
for (unsigned i = 0; i < sizeof(pcm); ++i)
|
||||||
|
pcm[i] = (uint8_t)(0xa0U + i);
|
||||||
|
|
||||||
|
CHECK(sendH2C(&fixture, KVMFR_AUDIO_MESSAGE_PLAYBACK_STOP,
|
||||||
|
wireGeneration, 0, 0, 0, 0, 0, NULL, 0));
|
||||||
|
CHECK(sendH2C(&fixture, KVMFR_AUDIO_MESSAGE_PLAYBACK_START,
|
||||||
|
wireGeneration, 0, 0, 0, 0, 0,
|
||||||
|
&format, sizeof(format)));
|
||||||
|
CHECK(sendH2C(&fixture, KVMFR_AUDIO_MESSAGE_PLAYBACK_DATA,
|
||||||
|
wireGeneration, 0, 0, 0, 0, 4, pcm, sizeof(pcm)));
|
||||||
|
|
||||||
|
CHECK(waitCount(&fixture, &fixture.trace.playStopCount, 1, WAIT_MS));
|
||||||
|
CHECK(waitCount(&fixture, &fixture.trace.playStartCount, 2, WAIT_MS));
|
||||||
|
CHECK(waitCount(&fixture, &fixture.trace.playDataCount, 1, WAIT_MS));
|
||||||
|
|
||||||
|
pthread_mutex_lock(&fixture.trace.mutex);
|
||||||
|
const unsigned eventCount = fixture.trace.eventCount;
|
||||||
|
const struct TraceEvent stopEvent = fixture.trace.events[eventBefore];
|
||||||
|
const struct TraceEvent startEvent = fixture.trace.events[eventBefore + 1];
|
||||||
|
const struct TraceEvent dataEvent = fixture.trace.events[eventBefore + 2];
|
||||||
|
const uint32_t dataGeneration = fixture.trace.playGeneration;
|
||||||
|
const size_t dataFrames = fixture.trace.playFrames;
|
||||||
|
uint8_t received[sizeof(pcm)];
|
||||||
|
memcpy(received, fixture.trace.playData, sizeof(received));
|
||||||
|
pthread_mutex_unlock(&fixture.trace.mutex);
|
||||||
|
|
||||||
|
CHECK(eventCount == eventBefore + 3);
|
||||||
|
CHECK(stopEvent.kind == TRACE_PLAY_STOP);
|
||||||
|
CHECK(stopEvent.generation == oldLocalGeneration);
|
||||||
|
CHECK(startEvent.kind == TRACE_PLAY_START);
|
||||||
|
CHECK(startEvent.generation != 0);
|
||||||
|
CHECK(startEvent.generation != oldLocalGeneration);
|
||||||
|
CHECK(dataEvent.kind == TRACE_PLAY_DATA);
|
||||||
|
CHECK(dataEvent.generation == startEvent.generation);
|
||||||
|
CHECK(dataGeneration == startEvent.generation);
|
||||||
|
CHECK(dataFrames == 4);
|
||||||
|
CHECK(!memcmp(received, pcm, sizeof(pcm)));
|
||||||
|
|
||||||
|
fixture.ops->detach(fixture.audio);
|
||||||
|
fixture.ops->setStatusListener(fixture.audio, NULL, NULL);
|
||||||
|
CHECK(readC2HType(&fixture, KVMFR_AUDIO_MESSAGE_RELEASE,
|
||||||
|
&message, payload, WAIT_MS));
|
||||||
|
CHECK(unbindBoth(&fixture));
|
||||||
|
const struct timespec settle = { .tv_nsec = 30000000L };
|
||||||
|
nanosleep(&settle, NULL);
|
||||||
|
|
||||||
|
fixtureCleanup(&fixture);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool testDataPlane(void)
|
static bool testDataPlane(void)
|
||||||
{
|
{
|
||||||
static const LG_AudioChannel expectedChannels[KVMFR_AUDIO_MAX_CHANNELS] =
|
static const LG_AudioChannel expectedChannels[KVMFR_AUDIO_MAX_CHANNELS] =
|
||||||
@@ -1279,6 +1362,9 @@ int main(void)
|
|||||||
if (!testRetiredClaim())
|
if (!testRetiredClaim())
|
||||||
return 1;
|
return 1;
|
||||||
++passed;
|
++passed;
|
||||||
|
if (!testPlaybackRestartSameGeneration())
|
||||||
|
return 1;
|
||||||
|
++passed;
|
||||||
if (!testDataPlane())
|
if (!testDataPlane())
|
||||||
return 1;
|
return 1;
|
||||||
++passed;
|
++passed;
|
||||||
@@ -1291,6 +1377,6 @@ int main(void)
|
|||||||
if (!testBoundDisconnect())
|
if (!testBoundDisconnect())
|
||||||
return 1;
|
return 1;
|
||||||
++passed;
|
++passed;
|
||||||
printf("PASS %u/6 client LGMP audio integration groups\n", passed);
|
printf("PASS %u/7 client LGMP audio integration groups\n", passed);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user