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

◆ parseMpeg1Info()

Mpeg1Info fl::Mpeg1::parseMpeg1Info ( fl::span< const fl::u8 > data,
fl::string * error_message = nullptr )
static

Definition at line 19 of file mpeg1.cpp.hpp.

19 {
20 Mpeg1Info info;
21
22 // Validate input data
23 if (data.empty()) {
24 if (error_message) {
25 *error_message = "Empty MPEG1 data";
26 }
27 return info; // returns invalid info
28 }
29
30 // Minimum size check - MPEG1 needs at least the pack header and system header
31 if (data.size() < 12) {
32 if (error_message) {
33 *error_message = "MPEG1 data too small";
34 }
35 return info;
36 }
37
38 // Check for MPEG1 start codes
39 // Look for Pack Start Code (0x000001BA) or System Start Code (0x000001BB)
40 bool foundMpegHeader = false;
41 fl::size headerOffset = 0;
42
43 for (fl::size i = 0; i <= data.size() - 4; i++) {
44 if (data[i] == 0x00 && data[i + 1] == 0x00 && data[i + 2] == 0x01) {
45 if (data[i + 3] == 0xBA || data[i + 3] == 0xBB) {
46 foundMpegHeader = true;
47 headerOffset = i;
48 break;
49 }
50 }
51 }
52
53 if (!foundMpegHeader) {
54 if (error_message) {
55 *error_message = "Invalid MPEG1 stream - no valid start code found";
56 }
57 return info;
58 }
59
60 // For detailed parsing, we need to use the actual decoder to extract metadata
61 // Since MPEG1 headers are complex, we'll use a temporary decoder instance
62 Mpeg1Config tempConfig;
63 tempConfig.mode = Mpeg1Config::SingleFrame;
64 tempConfig.skipAudio = true;
65
67 auto stream = fl::make_shared<fl::memorybuf>(data.size());
68 stream->write(data);
69
70 if (decoder->begin(stream)) {
71 // Extract metadata using decoder methods
72 info.width = decoder->getWidth();
73 info.height = decoder->getHeight();
74 info.frameRate = decoder->getFrameRate();
75 info.frameCount = decoder->getFrameCount();
76
77 // Calculate duration if we have frame count and frame rate
78 if (info.frameCount > 0 && info.frameRate > 0) {
79 info.duration = (info.frameCount * 1000) / info.frameRate;
80 }
81
82 // MPEG1 can have audio, but our decoder is configured to skip it
83 // In a real implementation, we'd parse the stream to detect audio tracks
84 info.hasAudio = false;
85 info.isValid = true;
86
87 decoder->end();
88 } else {
89 // Fallback: basic MPEG1 sequence header parsing
90 // Look for sequence header start code (0x000001B3)
91 for (fl::size i = headerOffset; i <= data.size() - 8; i++) {
92 if (data[i] == 0x00 && data[i + 1] == 0x00 &&
93 data[i + 2] == 0x01 && data[i + 3] == 0xB3) {
94
95 // Found sequence header, parse basic info
96 if (i + 7 < data.size()) {
97 // Width is in bits 4-15 of bytes 4-5
98 // Height is in bits 4-15 of bytes 6-7
99 fl::u16 width = ((data[i + 4] << 4) | ((data[i + 5] & 0xF0) >> 4));
100 fl::u16 height = (((data[i + 5] & 0x0F) << 8) | data[i + 6]);
101
102 if (width > 0 && height > 0) {
103 info.width = width;
104 info.height = height;
105 info.frameRate = 25; // Default assumption
106 info.frameCount = 0; // Unknown
107 info.duration = 0; // Unknown
108 info.hasAudio = false;
109 info.isValid = true;
110 }
111 }
112 break;
113 }
114 }
115
116 if (!info.isValid && error_message) {
117 *error_message = "Failed to parse MPEG1 stream metadata";
118 }
119 }
120
121 return info;
122}
constexpr bool empty() const FL_NOEXCEPT
Definition span.h:510
constexpr fl::size size() const FL_NOEXCEPT
Definition span.h:458
u8 u8 height
Definition blur.h:186
u8 width
Definition blur.h:186
shared_ptr< T > make_shared(Args &&... args) FL_NOEXCEPT
Definition shared_ptr.h:414
third_party::Mpeg1Config Mpeg1Config
Definition mpeg1.h:29

References fl::Mpeg1Info::duration, fl::span< T, Extent >::empty(), fl::Mpeg1Info::frameCount, fl::Mpeg1Info::frameRate, fl::Mpeg1Info::hasAudio, fl::height, fl::Mpeg1Info::height, fl::Mpeg1Info::isValid, fl::make_shared(), fl::third_party::Mpeg1Config::mode, fl::third_party::Mpeg1Config::SingleFrame, fl::span< T, Extent >::size(), fl::third_party::Mpeg1Config::skipAudio, fl::Mpeg1Info::width, and fl::width.

+ Here is the call graph for this function: