FastLED 3.9.15
Loading...
Searching...
No Matches

◆ initializeDecoder()

bool fl::third_party::SoftwareMpeg1Decoder::initializeDecoder ( )
private

Definition at line 251 of file software_decoder.cpp.hpp.

251 {
252 if (!stream_) {
253 setError("No input stream available");
254 return false;
255 }
256
257 // Read the entire stream into memory for pl_mpeg
258 // First, estimate the size by reading chunks
259 const fl::size CHUNK_SIZE = 8192;
260 fl::vector<fl::u8> tempBuffer;
261
262 fl::u8 chunk[CHUNK_SIZE];
263 fl::size bytesRead;
264 do {
265 bytesRead = stream_->read(chunk, CHUNK_SIZE);
266 if (bytesRead > 0) {
267 for (fl::size i = 0; i < bytesRead; ++i) {
268 tempBuffer.push_back(chunk[i]);
269 }
270 }
271 } while (bytesRead == CHUNK_SIZE);
272
273 if (tempBuffer.empty()) {
274 setError("Empty input stream - no data available");
275 return false;
276 }
277
278 // Copy to our buffer
279 decoderData_->totalSize = tempBuffer.size();
280 decoderData_->inputBuffer.reset(new fl::u8[decoderData_->totalSize]);
281 fl::memcpy(decoderData_->inputBuffer.get(), tempBuffer.data(), decoderData_->totalSize);
282
283 // Create pl_mpeg instance with memory buffer
285 decoderData_->inputBuffer.get(),
286 decoderData_->totalSize,
287 0 // Don't free when done - we manage the memory
288 );
289
290 if (!decoderData_->plmpeg) {
291 setError("Failed to create pl_mpeg decoder instance");
292 return false;
293 }
294
295 // Enable/disable audio decoding based on config
296 if (config_.skipAudio || !config_.audioCallback) {
298 } else {
302 }
303
304 // Set looping if requested
305 fl::third_party::plm_set_loop(decoderData_->plmpeg, config_.looping ? 1 : 0);
306
307 // Set up video decode callback BEFORE any decoding to ensure callbacks work
310
311 // Try to get headers - for multiplexed streams with audio, this may require decoding
312 // some frames before audio headers are found
313 // Note: Video callback must be set first so we can capture frame dimensions
315 // Temporarily allocate a minimal buffer for header decoding
316 // We'll reallocate properly once we know dimensions
317 fl::size temp_buffer_size = static_cast<fl::size>(1920ul * 1080ul * 3ul); // Max reasonable size for header decode
318 decoderData_->rgbFrameBuffer.reset(new fl::u8[temp_buffer_size]);
319
320 // Decode one frame to get headers
321 fl::third_party::plm_decode(decoderData_->plmpeg, decoderData_->targetFrameDuration);
322 }
323
324 // Check if we at least have video - video headers are mandatory
327 setError("Failed to parse MPEG1 headers");
328 return false;
329 }
330
331 // Audio headers might not be present yet if audio packets come later in the stream
332 // This is OK - audio will work once we encounter audio packets during decode
333
334 // Get video properties
335 decoderData_->width = static_cast<fl::u16>(fl::third_party::plm_get_width(decoderData_->plmpeg));
336 decoderData_->height = static_cast<fl::u16>(fl::third_party::plm_get_height(decoderData_->plmpeg));
337 decoderData_->frameRate = static_cast<fl::u16>(fl::third_party::plm_get_framerate(decoderData_->plmpeg));
338
339 if (decoderData_->width == 0 || decoderData_->height == 0) {
340 setError("Invalid video dimensions from MPEG1 stream");
341 return false;
342 }
343
344 // Now allocate properly sized buffers based on actual video dimensions
346 decoderData_->initialized = true;
347 decoderData_->headerParsed = true;
348 return true;
349}
void setError(const fl::string &message) FL_NOEXCEPT
static void audioDecodeCallback(fl::third_party::plm_t *plm, fl::third_party::plm_samples_t *samples, void *user) FL_NOEXCEPT
static void videoDecodeCallback(fl::third_party::plm_t *plm, fl::third_party::plm_frame_t *frame, void *user) FL_NOEXCEPT
fl::size size() const FL_NOEXCEPT
bool empty() const FL_NOEXCEPT
T * data() FL_NOEXCEPT
Definition vector.h:619
void push_back(const T &value) FL_NOEXCEPT
Definition vector.h:624
unsigned char u8
Definition coder.h:132
void plm_set_video_decode_callback(plm_t *self, plm_video_decode_callback fp, void *user) FL_NOEXCEPT
Definition pl_mpeg.hpp:464
void plm_decode(plm_t *self, double seconds) FL_NOEXCEPT
Definition pl_mpeg.hpp:474
int plm_get_width(plm_t *self) FL_NOEXCEPT
Definition pl_mpeg.hpp:388
int plm_get_height(plm_t *self) FL_NOEXCEPT
Definition pl_mpeg.hpp:394
plm_t * plm_create_with_memory(uint8_t *bytes, size_t length, int free_when_done) FL_NOEXCEPT
Definition pl_mpeg.hpp:244
void plm_set_audio_enabled(plm_t *self, int enabled) FL_NOEXCEPT
Definition pl_mpeg.hpp:344
void plm_set_loop(plm_t *self, int loop) FL_NOEXCEPT
Definition pl_mpeg.hpp:456
void plm_set_audio_decode_callback(plm_t *self, plm_audio_decode_callback fp, void *user) FL_NOEXCEPT
Definition pl_mpeg.hpp:469
double plm_get_framerate(plm_t *self) FL_NOEXCEPT
Definition pl_mpeg.hpp:400
int plm_has_headers(plm_t *self) FL_NOEXCEPT
Definition pl_mpeg.hpp:312
void * memcpy(void *dest, const void *src, size_t n) FL_NOEXCEPT

References allocateFrameBuffers(), audioDecodeCallback(), config_, fl::vector< T >::data(), decoderData_, fl::vector_basic::empty(), FL_NOEXCEPT, fl::memcpy(), fl::third_party::plm_create_with_memory(), fl::third_party::plm_decode(), fl::third_party::plm_get_framerate(), fl::third_party::plm_get_height(), fl::third_party::plm_get_width(), fl::third_party::plm_has_headers(), fl::third_party::plm_set_audio_decode_callback(), fl::third_party::plm_set_audio_enabled(), fl::third_party::plm_set_loop(), fl::third_party::plm_set_video_decode_callback(), fl::vector< T >::push_back(), setError(), fl::vector_basic::size(), stream_, and videoDecodeCallback().

Referenced by begin().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: