remotion-dev/remotion · error · std::io::Error
Not enough planes or linesizes
Error message
Not enough planes or linesizes
What it means
Thrown by get_dimensions_from_planes when decoding a YUV420P frame whose plane/linesize arrays have fewer than 3 entries. The function derives width/height from Y/U/V planes, so all three planes and linesizes must be present for any format other than YUV420P (which returns early with the original dimensions). This indicates malformed or truncated decoded frame data passed from ffmpeg.
Source
Thrown at packages/compositor/rust/fix_dimensions.rs:18
use std::io::ErrorKind;
use ffmpeg_next::format::Pixel;
// Calculate dimensions based on linesize, not based on metadata
pub fn get_dimensions_from_planes(
pixel_format: Pixel,
planes: &[Vec<u8>],
linesizes: &[i32; 8],
original_width: u32,
original_height: u32,
) -> Result<(u32, u32), std::io::Error> {
if pixel_format != Pixel::YUV420P {
return Ok((original_width, original_height));
}
if planes.len() < 3 || linesizes.len() < 3 {
return Err(std::io::Error::new(
ErrorKind::Other,
"Not enough planes or linesizes",
));
}
// Calculate dimensions for each plane based on linesizes
let y_height = planes[0].len() as u32 / linesizes[0] as u32;
let y_width = linesizes[0] as u32;
// Believe the original width, but do not allow overflow
Ok((y_width.min(original_width), y_height.min(original_height)))
}
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Re-encode or replace the source media with a valid YUV420P file that ffmpeg can fully decode.
- Before calling, assert planes.len() >= 3 and that linesizes[0..3] are non-zero, falling back to original_width/original_height if not.
- Upgrade/rematch the ffmpeg-next crate version to one consistent with the linked ffmpeg libraries.
Example fix
// before
let dims = get_dimensions_from_planes(fmt, &planes, &linesizes, w, h)?;
// after
if fmt == Pixel::YUV420P && (planes.len() < 3 || linesizes[0] == 0 || linesizes[1] == 0 || linesizes[2] == 0) {
return Ok((w, h)); // fall back, do not crash on partial planes
}
let dims = get_dimensions_from_planes(fmt, &planes, &linesizes, w, h)?; Defensive patterns
Strategy: validation
Validate before calling
fn can_get_dimensions(pixel_format: Pixel, planes: &[Vec<u8>], linesizes: &[i32; 8]) -> bool {
if pixel_format != Pixel::YUV420P { return true; }
planes.len() >= 3 && linesizes[0] > 0 && linesizes[1] > 0 && linesizes[2] > 0
}
// call before get_dimensions_from_planes; fall back to (original_width, original_height) Type guard
null
Try / catch
match get_dimensions_from_planes(fmt, &planes, &linesizes, w, h) {
Ok(d) => d,
Err(_) => (w, h), // tolerate partial planes, use declared dims
} Prevention
- Reject/truncate sources ffmpeg cannot fully decode.
- Keep the ffmpeg-next crate version in sync with linked libraries.
- Unit-test the YUV420P path with synthetic 3-plane frames.
When it happens
Trigger: Calling get_dimensions_from_planes with pixel_format == Pixel::YUV420P but planes.len() < 3 or linesizes containing fewer than 3 populated slots (the array is fixed at 8 but only some are set by the decoder). Happens when a hardware/decoded frame surfaces incomplete plane data, or an upstream filter drops subplanes.
Common situations: Corrupt or truncated source media where ffmpeg partially decodes YUV420P; mismatches between the ffmpeg-next version and the planes the decoder emits; feeding manually-constructed plane arrays that omit chroma planes.
Related errors
- No frame found at position {} for source {} (original source
- Odd rotation angle
- No audio stream found in '${input_path}'. Ensure the video c
- Could not find audio stream in ${src}
- No video stream found in ${file_path}. Is this a video file?
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/3b3ed5773fceafec.
Report an issue: GitHub.