FastLED 3.9.7
Loading...
Searching...
No Matches
pixel_stream.cpp
1
2#include "fx/video/pixel_stream.h"
3#include "fl/namespace.h"
4#include "fl/dbg.h"
5
6#ifndef INT32_MAX
7#define INT32_MAX 0x7fffffff
8#endif
9
10#define DBG FASTLED_DBG
11
12using fl::FileHandlePtr;
13using fl::ByteStreamPtr;
14
15namespace fl {
16
17PixelStream::PixelStream(int bytes_per_frame) : mbytesPerFrame(bytes_per_frame), mUsingByteStream(false) {
18}
19
20PixelStream::~PixelStream() {
21 close();
22}
23
24bool PixelStream::begin(FileHandlePtr h) {
25 close();
26 mFileHandle = h;
27 mUsingByteStream = false;
28 return mFileHandle->available();
29}
30
31bool PixelStream::beginStream(ByteStreamPtr s) {
32 close();
33 mByteStream = s;
34 mUsingByteStream = true;
35 return mByteStream->available(mbytesPerFrame);
36}
37
38void PixelStream::close() {
39 if (!mUsingByteStream && mFileHandle) {
40 mFileHandle.reset();
41 }
42 mByteStream.reset();
43 mFileHandle.reset();
44}
45
46int32_t PixelStream::bytesPerFrame() {
47 return mbytesPerFrame;
48}
49
50bool PixelStream::readPixel(CRGB* dst) {
51 if (mUsingByteStream) {
52 return mByteStream->read(&dst->r, 1) && mByteStream->read(&dst->g, 1) && mByteStream->read(&dst->b, 1);
53 } else {
54 return mFileHandle->read(&dst->r, 1) && mFileHandle->read(&dst->g, 1) && mFileHandle->read(&dst->b, 1);
55 }
56}
57
58bool PixelStream::available() const {
59 if (mUsingByteStream) {
60 return mByteStream->available(mbytesPerFrame);
61 } else {
62 return mFileHandle->available();
63 }
64}
65
66bool PixelStream::atEnd() const {
67 if (mUsingByteStream) {
68 return false;
69 } else {
70 return !mFileHandle->available();
71 }
72}
73
74bool PixelStream::readFrame(Frame* frame) {
75 if (!frame) {
76 return false;
77 }
78 if (!mUsingByteStream) {
79 if (!framesRemaining()) {
80 return false;
81 }
82 size_t n = mFileHandle->readCRGB(frame->rgb(), mbytesPerFrame / 3);
83 DBG("pos: " << mFileHandle->pos());
84 return n*3 == size_t(mbytesPerFrame);
85 }
86 size_t n = mByteStream->readCRGB(frame->rgb(), mbytesPerFrame / 3);
87 return n*3 == size_t(mbytesPerFrame);
88}
89
90bool PixelStream::hasFrame(uint32_t frameNumber) {
91 if (mUsingByteStream) {
92 // ByteStream doesn't support seeking
93 DBG("Not implemented and therefore always returns true");
94 return true;
95 } else {
96 size_t total_bytes = mFileHandle->size();
97 return frameNumber * mbytesPerFrame < total_bytes;
98 }
99}
100
101bool PixelStream::readFrameAt(uint32_t frameNumber, Frame* frame) {
102 // DBG("read frame at " << frameNumber);
103 if (mUsingByteStream) {
104 // ByteStream doesn't support seeking
105 FASTLED_DBG("ByteStream doesn't support seeking");
106 return false;
107 } else {
108 // DBG("mbytesPerFrame: " << mbytesPerFrame);
109 mFileHandle->seek(frameNumber * mbytesPerFrame);
110 if (mFileHandle->bytesLeft() == 0) {
111 return false;
112 }
113 size_t read = mFileHandle->readCRGB(frame->rgb(), mbytesPerFrame / 3) * 3;
114 // DBG("read: " << read);
115 // DBG("pos: " << mFileHandle->Position());
116
117 bool ok = int(read) == mbytesPerFrame;
118 if (!ok) {
119 DBG("readFrameAt failed - read: " << read << ", mbytesPerFrame: " << mbytesPerFrame << ", frame:" << frameNumber << ", left: " << mFileHandle->bytesLeft());
120 }
121 return ok;
122 }
123}
124
125int32_t PixelStream::framesRemaining() const {
126 if (mbytesPerFrame == 0) return 0;
127 int32_t bytes_left = bytesRemaining();
128 if (bytes_left <= 0) {
129 return 0;
130 }
131 return bytes_left / mbytesPerFrame;
132}
133
134int32_t PixelStream::framesDisplayed() const {
135 if (mUsingByteStream) {
136 // ByteStream doesn't have a concept of total size, so we can't calculate this
137 return -1;
138 } else {
139 int32_t bytes_played = mFileHandle->pos();
140 return bytes_played / mbytesPerFrame;
141 }
142}
143
144int32_t PixelStream::bytesRemaining() const {
145 if (mUsingByteStream) {
146 return INT32_MAX;
147 } else {
148 return mFileHandle->bytesLeft();
149 }
150}
151
152int32_t PixelStream::bytesRemainingInFrame() const {
153 return bytesRemaining() % mbytesPerFrame;
154}
155
156bool PixelStream::rewind() {
157 if (mUsingByteStream) {
158 // ByteStream doesn't support rewinding
159 return false;
160 } else {
161 mFileHandle->seek(0);
162 return true;
163 }
164}
165
166PixelStream::Type PixelStream::getType() const {
167 return mUsingByteStream ? Type::kStreaming : Type::kFile;
168}
169
170size_t PixelStream::readBytes(uint8_t* dst, size_t len) {
171 uint16_t bytesRead = 0;
172 if (mUsingByteStream) {
173 while (bytesRead < len && mByteStream->available(len)) {
174 // use pop_front()
175 if (mByteStream->read(dst + bytesRead, 1)) {
176 bytesRead++;
177 } else {
178 break;
179 }
180 }
181 } else {
182 while (bytesRead < len && mFileHandle->available()) {
183 if (mFileHandle->read(dst + bytesRead, 1)) {
184 bytesRead++;
185 } else {
186 break;
187 }
188 }
189 }
190 return bytesRead;
191}
192
193} // namespace fl
Implements the FastLED namespace macros.
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:54
uint8_t r
Red channel value.
Definition crgb.h:58
uint8_t g
Green channel value.
Definition crgb.h:62
uint8_t b
Blue channel value.
Definition crgb.h:66