first commit

This commit is contained in:
stuce-bot 2025-06-30 20:47:33 +02:00
commit 5893b00dd2
1669 changed files with 1982740 additions and 0 deletions

View file

@ -0,0 +1,232 @@
// g++ --std=c++11 test.cpp
#include "test.h"
#include <vector>
#include "crgb.h"
#include "fl/bytestreammemory.h"
#include "fl/ptr.h"
#include "fx/video.h"
#include "fx/video/pixel_stream.h"
#include "lib8tion/intmap.h"
#include "test.h"
#include "fl/namespace.h"
#define FPS 30
#define FRAME_TIME 1000 / FPS
#define VIDEO_WIDTH 10
#define VIDEO_HEIGHT 10
#define LEDS_PER_FRAME VIDEO_WIDTH *VIDEO_HEIGHT
FASTLED_SMART_PTR(FakeFileHandle);
using namespace fl;
class FakeFileHandle : public FileHandle {
public:
virtual ~FakeFileHandle() {}
bool available() const override { return mPos < data.size(); }
size_t bytesLeft() const override { return data.size() - mPos; }
size_t size() const override { return data.size(); }
bool valid() const override { return true; }
size_t write(const uint8_t *src, size_t len) {
data.insert(data.end(), src, src + len);
return len;
}
size_t writeCRGB(const CRGB *src, size_t len) {
size_t bytes_written = write((const uint8_t *)src, len * 3);
return bytes_written / 3;
}
size_t read(uint8_t *dst, size_t bytesToRead) override {
size_t bytesRead = 0;
while (bytesRead < bytesToRead && mPos < data.size()) {
dst[bytesRead] = data[mPos];
bytesRead++;
mPos++;
}
return bytesRead;
}
size_t pos() const override { return mPos; }
const char *path() const override { return "fake"; }
bool seek(size_t pos) override {
this->mPos = pos;
return true;
}
void close() override {}
std::vector<uint8_t> data;
size_t mPos = 0;
};
TEST_CASE("video with memory stream") {
// Video video(LEDS_PER_FRAME, FPS);
Video video(LEDS_PER_FRAME, FPS, 1);
video.setFade(0, 0);
ByteStreamMemoryPtr memoryStream =
ByteStreamMemoryPtr::New(LEDS_PER_FRAME * 3);
CRGB testData[LEDS_PER_FRAME] = {};
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
testData[i] = i % 2 == 0 ? CRGB::Red : CRGB::Black;
}
size_t pixels_written = memoryStream->writeCRGB(testData, LEDS_PER_FRAME);
REQUIRE_EQ(pixels_written, LEDS_PER_FRAME);
video.beginStream(memoryStream);
CRGB leds[LEDS_PER_FRAME];
bool ok = video.draw(FRAME_TIME + 1, leds);
REQUIRE(ok);
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
CHECK_EQ(leds[i], testData[i]);
}
ok = video.draw(2 * FRAME_TIME + 1, leds);
REQUIRE(ok);
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
// CHECK_EQ(leds[i], testData[i]);
REQUIRE_EQ(leds[i].r, testData[i].r);
REQUIRE_EQ(leds[i].g, testData[i].g);
REQUIRE_EQ(leds[i].b, testData[i].b);
}
}
TEST_CASE("video with memory stream, interpolated") {
// Video video(LEDS_PER_FRAME, FPS);
Video video(LEDS_PER_FRAME, 1);
video.setFade(0, 0);
ByteStreamMemoryPtr memoryStream =
ByteStreamMemoryPtr::New(LEDS_PER_FRAME * sizeof(CRGB) * 2);
CRGB testData[LEDS_PER_FRAME] = {};
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
testData[i] = CRGB::Red;
}
size_t pixels_written = memoryStream->writeCRGB(testData, LEDS_PER_FRAME);
CHECK_EQ(pixels_written, LEDS_PER_FRAME);
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
testData[i] = CRGB::Black;
}
pixels_written = memoryStream->writeCRGB(testData, LEDS_PER_FRAME);
CHECK_EQ(pixels_written, LEDS_PER_FRAME);
video.beginStream(memoryStream); // One frame per second.
CRGB leds[LEDS_PER_FRAME];
bool ok = video.draw(0, leds); // First frame starts time 0.
ok = video.draw(500, leds); // Half a frame.
CHECK(ok);
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
int r = leds[i].r;
int g = leds[i].g;
int b = leds[i].b;
REQUIRE_EQ(128, r); // We expect the color to be interpolated to 128.
REQUIRE_EQ(0, g);
REQUIRE_EQ(0, b);
}
}
TEST_CASE("video with file handle") {
// Video video(LEDS_PER_FRAME, FPS);
Video video(LEDS_PER_FRAME, FPS);
video.setFade(0, 0);
FakeFileHandlePtr fileHandle = FakeFileHandlePtr::New();
CRGB led_frame[LEDS_PER_FRAME];
// alternate between red and black
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
led_frame[i] = i % 2 == 0 ? CRGB::Red : CRGB::Black;
}
// now write the data
size_t leds_written = fileHandle->writeCRGB(led_frame, LEDS_PER_FRAME);
CHECK_EQ(leds_written, LEDS_PER_FRAME);
video.begin(fileHandle);
CRGB leds[LEDS_PER_FRAME];
bool ok = video.draw(FRAME_TIME + 1, leds);
REQUIRE(ok);
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
CHECK_EQ(leds[i], led_frame[i]);
}
ok = video.draw(2 * FRAME_TIME + 1, leds);
CHECK(ok);
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
CHECK_EQ(leds[i], led_frame[i]);
}
}
TEST_CASE("Video duration") {
Video video(LEDS_PER_FRAME, FPS);
FakeFileHandlePtr fileHandle = FakeFileHandlePtr::New();
CRGB led_frame[LEDS_PER_FRAME];
// just set all the leds to white
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
led_frame[i] = CRGB::White;
}
// fill frames for all of one second
for (uint32_t i = 0; i < FPS; i++) {
size_t leds_written = fileHandle->writeCRGB(led_frame, LEDS_PER_FRAME);
CHECK_EQ(leds_written, LEDS_PER_FRAME);
}
video.begin(fileHandle);
int32_t duration = video.durationMicros();
float duration_f = duration / 1000.0;
CHECK_EQ(1000, uint32_t(duration_f + 0.5));
}
TEST_CASE("video with end frame fadeout") {
Video video(LEDS_PER_FRAME, FPS);
video.setFade(0, 1000);
FakeFileHandlePtr fileHandle = FakeFileHandlePtr::New();
CRGB led_frame[LEDS_PER_FRAME];
// just set all the leds to white
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
led_frame[i] = CRGB::White;
}
// fill frames for all of one second
for (uint32_t i = 0; i < FPS; i++) {
size_t leds_written = fileHandle->writeCRGB(led_frame, LEDS_PER_FRAME);
CHECK_EQ(leds_written, LEDS_PER_FRAME);
}
video.begin(fileHandle);
CRGB leds[LEDS_PER_FRAME];
bool ok = video.draw(0, leds);
REQUIRE(ok);
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
CHECK_EQ(leds[i], led_frame[i]);
}
ok = video.draw(500, leds);
// test that the leds are about half as bright
REQUIRE(ok);
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
// This is what the values should be but we don't do inter-frame
// interpolation yet. CHECK_EQ(leds[i].r, 127); CHECK_EQ(leds[i].g,
// 127); CHECK_EQ(leds[i].b, 127);
CHECK_EQ(leds[i].r, 110);
CHECK_EQ(leds[i].g, 110);
CHECK_EQ(leds[i].b, 110);
}
ok = video.draw(900, leds); // close to last frame
REQUIRE(ok);
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
CHECK_EQ(leds[i].r, 8);
CHECK_EQ(leds[i].g, 8);
CHECK_EQ(leds[i].b, 8);
}
ok = video.draw(965, leds); // Last frame
REQUIRE(ok);
// test that the leds are almost black
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
REQUIRE_EQ(leds[i], CRGB(0, 0, 0));
}
#if 0 // Bug - we do not handle wrapping around
ok = video.draw(1000, leds); // Bug - we have to let the buffer drain with one frame.
ok = video.draw(1000, leds); // After last frame we flip around
for (uint32_t i = 0; i < LEDS_PER_FRAME; i++) {
REQUIRE_EQ(leds[i], CRGB(4, 4, 4));
}
#endif //
}