MCPcopy Create free account
hub / github.com/FastLED/FastLED / decode

Method decode

src/platforms/esp/32/codec/h264_hw_decoder.hpp:212–274  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

210}
211
212DecodeResult H264HwDecoder::decode() FL_NOEXCEPT {
213 if (!mImpl->ready || !mImpl->decoder) return DecodeResult::Error;
214 if (mImpl->frameDecoded) return DecodeResult::EndOfStream;
215
216 const fl::u16 w = mImpl->info.width;
217 const fl::u16 h = mImpl->info.height;
218
219 // Split Annex B stream into individual NAL units
220 fl::vector<NalUnit> nalUnits = splitAnnexB(mImpl->annexB);
221 if (nalUnits.empty()) {
222 mImpl->error = true;
223 mImpl->errorMsg = "No NAL units found in Annex B stream";
224 return DecodeResult::Error;
225 }
226
227 // Feed each NAL unit to decoder until we get a frame
228 for (fl::size i = 0; i < nalUnits.size(); i++) {
229 esp_h264_dec_in_frame_t in_frame = {};
230 in_frame.raw_data.buffer = const_cast<fl::u8*>(nalUnits[i].data);
231 in_frame.raw_data.len = static_cast<fl::u32>(nalUnits[i].len);
232
233 esp_h264_dec_out_frame_t out_frame = {};
234
235 esp_h264_err_t err = esp_h264_dec_process(mImpl->decoder, &in_frame, &out_frame);
236 if (err != ESP_H264_ERR_OK) {
237 continue; // SPS/PPS NALUs may not produce output
238 }
239
240 if (out_frame.out_size > 0 && out_frame.outbuf != nullptr) {
241 // YUV420P (I420) → RGB888 conversion
242 const fl::u32 pixelCount = static_cast<fl::u32>(w) * static_cast<fl::u32>(h);
243 const fl::u8* yPlane = out_frame.outbuf;
244 const fl::u8* uPlane = out_frame.outbuf + pixelCount;
245 const fl::u8* vPlane = uPlane + pixelCount / 4;
246
247 fl::vector<fl::u8> rgbBuf(pixelCount * 3) FL_NOEXCEPT;
248 fl::u8* dst = rgbBuf.data();
249
250 for (fl::u16 row = 0; row < h; row++) {
251 for (fl::u16 col = 0; col < w; col++) {
252 int y = yPlane[row * w + col];
253 int u = uPlane[(row / 2) * (w / 2) + (col / 2)];
254 int v = vPlane[(row / 2) * (w / 2) + (col / 2)];
255
256 // BT.601 YUV→RGB fixed-point
257 int d = u - 128;
258 int e = v - 128;
259 *dst++ = clampU8(y + ((359 * e + 128) >> 8)); // R
260 *dst++ = clampU8(y - ((88 * d + 183 * e + 128) >> 8)); // G
261 *dst++ = clampU8(y + ((454 * d + 128) >> 8)); // B
262 }
263 }
264
265 mImpl->currentFrame = Frame(rgbBuf.data(), w, h, PixelFormat::RGB888, 0);
266 mImpl->frameDecoded = true;
267 return DecodeResult::Success;
268 }
269 }

Callers

nothing calls this directly

Calls 6

splitAnnexBFunction · 0.85
clampU8Function · 0.85
FrameClass · 0.50
emptyMethod · 0.45
sizeMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected