Decode high bit-depth videos as 16-bits-per-channel PNGs.

This commit is contained in:
Nathan Vegdahl 2022-04-19 17:34:32 -07:00
parent 702e6ac1e1
commit e0c570d26c

View File

@ -32,73 +32,860 @@ fn main() {
// Create a converter to get the video frames into the color format // Create a converter to get the video frames into the color format
// we want. // we want.
// It's a bit weird, but we do this by creating a scaler, which also let bit_depth = pixel_channel_size(decoder.format()).unwrap_or(8);
// resizes images. Apparently it's an all-in-one kind of thing for let mut converter = decoder
// scaling and color format conversion. .converter(if bit_depth <= 8 {
let mut converter = ffmpeg::software::scaling::context::Context::get( Pixel::RGB24
decoder.format(), } else {
decoder.width(), // Note: don't use plain `RGB48`, because it doesn't work
decoder.height(), // for some reason. Always use either the `BE` or `LE`
Pixel::RGB24, // Output color format. // variant, as appropriate for the platform.
decoder.width(), Pixel::RGB48BE
decoder.height(), })
Flags::POINT, // Nearest neighbor, since we're not actually scaling. .unwrap();
)
.unwrap();
// Place to store the image data.
let mut width = 0;
let mut height = 0;
let mut pixels = Vec::new();
// Get the first frame of the video. // Get the first frame of the video.
// To access it we have to process packets until the frame is let mut frame = None;
// available. {
let mut decoded_frame = ffmpeg::util::frame::video::Video::empty(); // To access a frame we have to process packets until a frame is
for (stream, packet) in input_ctx.packets() { // available.
if stream.index() == stream_idx { let mut decoded_frame = ffmpeg::util::frame::video::Video::empty();
decoder.send_packet(&packet).unwrap(); for (stream, packet) in input_ctx.packets() {
if decoder.receive_frame(&mut decoded_frame).is_ok() { if stream.index() == stream_idx {
// Convert to RGB. decoder.send_packet(&packet).unwrap();
let mut converted_frame = ffmpeg::util::frame::video::Video::empty(); if decoder.receive_frame(&mut decoded_frame).is_ok() {
converter.run(&decoded_frame, &mut converted_frame).unwrap(); // Convert to RGB.
let mut converted_frame = ffmpeg::util::frame::video::Video::empty();
converter.run(&decoded_frame, &mut converted_frame).unwrap();
// Save the image data to our own in-memory area. // We got the first frame, so stop.
width = converted_frame.width() as u32; frame = Some(converted_frame);
height = converted_frame.height() as u32; break;
// The `0` parameter is the plane. For this pixel format
// there's just one plane anyway.
for byte in converted_frame.data(0).iter() {
pixels.push(*byte);
} }
// We got the first frame, so stop.
break;
} }
} }
} }
// Write out a PNG file. // Write out a PNG file of the frame.
let mut encoder = png::Encoder::new( if let Some(frame) = frame {
BufWriter::new(File::create(output_path).unwrap()), let mut encoder = png::Encoder::new(
width, BufWriter::new(File::create(output_path).unwrap()),
height, frame.width(),
); frame.height(),
encoder.set_color(png::ColorType::Rgb); );
encoder.set_depth(png::BitDepth::Eight); encoder.set_color(png::ColorType::Rgb);
let mut writer = encoder.write_header().unwrap(); encoder.set_depth(if bit_depth <= 8 {
writer.write_image_data(&pixels).unwrap(); png::BitDepth::Eight
} else {
png::BitDepth::Sixteen
});
let mut writer = encoder.write_header().unwrap();
writer.write_image_data(frame.data(0)).unwrap();
println!("{:?}", decoder.format()); println!("Done");
} else {
println!("Could not process video.");
}
} }
// Returns the number of bits needed to store any of the pixel channels // Returns the number of bits needed to store any of the pixel channels
// for a given format. // for a given format.
fn pixel_channel_size(f: Pixel) -> usize { fn pixel_channel_size(f: Pixel) -> Option<usize> {
use Pixel::*;
match f { match f {
YUV420P => 8, // No specific pixel format defined.
YUV422P10LE => 10, Pixel::None => None,
_ => panic!("Haven't decided how to decode '{:?}' yet", f), Pixel::VAAPI_MOCO => None,
Pixel::VAAPI_IDCT => None,
Pixel::VAAPI_VLD => None,
Pixel::DXVA2_VLD => None,
Pixel::VDPAU => None,
Pixel::QSV => None,
Pixel::MMAL => None,
Pixel::D3D11VA_VLD => None,
Pixel::CUDA => None,
Pixel::XVMC => None,
Pixel::VIDEOTOOLBOX => None,
Pixel::MEDIACODEC => None,
Pixel::D3D11 => None,
Pixel::DRM_PRIME => None,
Pixel::OPENCL => None,
Pixel::VULKAN => None,
// Defined pixel formats.
Pixel::YUV420P => Some(8),
Pixel::YUYV422 => Some(8),
Pixel::RGB24 => Some(8),
Pixel::BGR24 => Some(8),
Pixel::YUV422P => Some(8),
Pixel::YUV444P => Some(8),
Pixel::YUV410P => Some(8),
Pixel::YUV411P => Some(8),
Pixel::GRAY8 => Some(8),
Pixel::MonoWhite => Some(1),
Pixel::MonoBlack => Some(1),
Pixel::PAL8 => Some(8),
Pixel::YUVJ420P => Some(8),
Pixel::YUVJ422P => Some(8),
Pixel::YUVJ444P => Some(8),
Pixel::UYVY422 => Some(8),
Pixel::UYYVYY411 => Some(8),
Pixel::BGR8 => Some(3),
Pixel::BGR4 => Some(2),
Pixel::BGR4_BYTE => Some(2),
Pixel::RGB8 => Some(3),
Pixel::RGB4 => Some(2),
Pixel::RGB4_BYTE => Some(2),
Pixel::NV12 => Some(8),
Pixel::NV21 => Some(8),
Pixel::ARGB => Some(8),
Pixel::RGBA => Some(8),
Pixel::ABGR => Some(8),
Pixel::BGRA => Some(8),
Pixel::GRAY16BE => Some(16),
Pixel::GRAY16LE => Some(16),
Pixel::YUV440P => Some(8),
Pixel::YUVJ440P => Some(8),
Pixel::YUVA420P => Some(8),
Pixel::RGB48BE => Some(16),
Pixel::RGB48LE => Some(16),
Pixel::RGB565BE => Some(6),
Pixel::RGB565LE => Some(6),
Pixel::RGB555BE => Some(5),
Pixel::RGB555LE => Some(5),
Pixel::BGR565BE => Some(6),
Pixel::BGR565LE => Some(6),
Pixel::BGR555BE => Some(5),
Pixel::BGR555LE => Some(5),
Pixel::YUV420P16LE => Some(16),
Pixel::YUV420P16BE => Some(16),
Pixel::YUV422P16LE => Some(16),
Pixel::YUV422P16BE => Some(16),
Pixel::YUV444P16LE => Some(16),
Pixel::YUV444P16BE => Some(16),
Pixel::RGB444LE => Some(4),
Pixel::RGB444BE => Some(4),
Pixel::BGR444LE => Some(4),
Pixel::BGR444BE => Some(4),
Pixel::YA8 => Some(8),
Pixel::BGR48BE => Some(16),
Pixel::BGR48LE => Some(16),
Pixel::YUV420P9BE => Some(9),
Pixel::YUV420P9LE => Some(9),
Pixel::YUV420P10BE => Some(10),
Pixel::YUV420P10LE => Some(10),
Pixel::YUV422P10BE => Some(10),
Pixel::YUV422P10LE => Some(10),
Pixel::YUV444P9BE => Some(9),
Pixel::YUV444P9LE => Some(9),
Pixel::YUV444P10BE => Some(10),
Pixel::YUV444P10LE => Some(10),
Pixel::YUV422P9BE => Some(9),
Pixel::YUV422P9LE => Some(9),
Pixel::GBRP => Some(8),
Pixel::GBRP9BE => Some(9),
Pixel::GBRP9LE => Some(9),
Pixel::GBRP10BE => Some(10),
Pixel::GBRP10LE => Some(10),
Pixel::GBRP16BE => Some(16),
Pixel::GBRP16LE => Some(16),
Pixel::YUVA420P9BE => Some(9),
Pixel::YUVA420P9LE => Some(9),
Pixel::YUVA422P9BE => Some(9),
Pixel::YUVA422P9LE => Some(9),
Pixel::YUVA444P9BE => Some(9),
Pixel::YUVA444P9LE => Some(9),
Pixel::YUVA420P10BE => Some(10),
Pixel::YUVA420P10LE => Some(10),
Pixel::YUVA422P10BE => Some(10),
Pixel::YUVA422P10LE => Some(10),
Pixel::YUVA444P10BE => Some(10),
Pixel::YUVA444P10LE => Some(10),
Pixel::YUVA420P16BE => Some(16),
Pixel::YUVA420P16LE => Some(16),
Pixel::YUVA422P16BE => Some(16),
Pixel::YUVA422P16LE => Some(16),
Pixel::YUVA444P16BE => Some(16),
Pixel::YUVA444P16LE => Some(16),
Pixel::XYZ12LE => Some(12),
Pixel::XYZ12BE => Some(12),
Pixel::NV16 => Some(8),
Pixel::NV20LE => Some(10),
Pixel::NV20BE => Some(10),
Pixel::RGBA64BE => Some(16),
Pixel::RGBA64LE => Some(16),
Pixel::BGRA64BE => Some(16),
Pixel::BGRA64LE => Some(16),
Pixel::YVYU422 => Some(8),
Pixel::YA16BE => Some(16),
Pixel::YA16LE => Some(16),
Pixel::ZRGB => Some(8),
Pixel::RGBZ => Some(8),
Pixel::ZBGR => Some(8),
Pixel::BGRZ => Some(8),
Pixel::YUVA444P => Some(8),
Pixel::YUVA422P => Some(8),
Pixel::YUV420P12BE => Some(12),
Pixel::YUV420P12LE => Some(12),
Pixel::YUV420P14BE => Some(14),
Pixel::YUV420P14LE => Some(14),
Pixel::YUV422P12BE => Some(12),
Pixel::YUV422P12LE => Some(12),
Pixel::YUV422P14BE => Some(14),
Pixel::YUV422P14LE => Some(14),
Pixel::YUV444P12BE => Some(12),
Pixel::YUV444P12LE => Some(12),
Pixel::YUV444P14BE => Some(14),
Pixel::YUV444P14LE => Some(14),
Pixel::GBRP12BE => Some(12),
Pixel::GBRP12LE => Some(12),
Pixel::GBRP14BE => Some(14),
Pixel::GBRP14LE => Some(14),
Pixel::GBRAP => Some(8),
Pixel::GBRAP16BE => Some(16),
Pixel::GBRAP16LE => Some(16),
Pixel::YUVJ411P => Some(8),
Pixel::BAYER_BGGR8 => Some(8),
Pixel::BAYER_RGGB8 => Some(8),
Pixel::BAYER_GBRG8 => Some(8),
Pixel::BAYER_GRBG8 => Some(8),
Pixel::BAYER_BGGR16LE => Some(16),
Pixel::BAYER_BGGR16BE => Some(16),
Pixel::BAYER_RGGB16LE => Some(16),
Pixel::BAYER_RGGB16BE => Some(16),
Pixel::BAYER_GBRG16LE => Some(16),
Pixel::BAYER_GBRG16BE => Some(16),
Pixel::BAYER_GRBG16LE => Some(16),
Pixel::BAYER_GRBG16BE => Some(16),
Pixel::YUV440P10LE => Some(10),
Pixel::YUV440P10BE => Some(10),
Pixel::YUV440P12LE => Some(12),
Pixel::YUV440P12BE => Some(12),
Pixel::AYUV64LE => Some(16),
Pixel::AYUV64BE => Some(16),
Pixel::P010LE => Some(10),
Pixel::P010BE => Some(10),
Pixel::GBRAP12BE => Some(12),
Pixel::GBRAP12LE => Some(12),
Pixel::GBRAP10LE => Some(10),
Pixel::GBRAP10BE => Some(10),
Pixel::GRAY12BE => Some(12),
Pixel::GRAY12LE => Some(12),
Pixel::GRAY10BE => Some(10),
Pixel::GRAY10LE => Some(10),
Pixel::P016LE => Some(16),
Pixel::P016BE => Some(16),
Pixel::GRAY9BE => Some(9),
Pixel::GRAY9LE => Some(9),
Pixel::GBRPF32BE => Some(32),
Pixel::GBRPF32LE => Some(32),
Pixel::GBRAPF32BE => Some(32),
Pixel::GBRAPF32LE => Some(32),
Pixel::GRAY14BE => Some(14),
Pixel::GRAY14LE => Some(14),
Pixel::GRAYF32BE => Some(32),
Pixel::GRAYF32LE => Some(32),
Pixel::YUVA422P12BE => Some(12),
Pixel::YUVA422P12LE => Some(12),
Pixel::YUVA444P12BE => Some(12),
Pixel::YUVA444P12LE => Some(12),
Pixel::NV24 => Some(8),
Pixel::NV42 => Some(8),
Pixel::Y210BE => Some(10),
Pixel::Y210LE => Some(10),
Pixel::X2RGB10LE => Some(10),
Pixel::X2RGB10BE => Some(10),
// Native-endian aliases for some of the above formats.
Pixel::RGB32 => Some(8),
Pixel::RGB32_1 => Some(8),
Pixel::BGR32 => Some(8),
Pixel::BGR32_1 => Some(8),
Pixel::ZRGB32 => Some(8),
Pixel::ZBGR32 => Some(8),
Pixel::GRAY16 => Some(16),
Pixel::YA16 => Some(16),
Pixel::RGB48 => Some(16),
Pixel::RGB565 => Some(6),
Pixel::RGB555 => Some(5),
Pixel::RGB444 => Some(4),
Pixel::BGR48 => Some(16),
Pixel::BGR565 => Some(6),
Pixel::BGR555 => Some(5),
Pixel::BGR444 => Some(4),
Pixel::YUV420P9 => Some(9),
Pixel::YUV422P9 => Some(9),
Pixel::YUV444P9 => Some(9),
Pixel::YUV420P10 => Some(10),
Pixel::YUV422P10 => Some(10),
Pixel::YUV440P10 => Some(10),
Pixel::YUV444P10 => Some(10),
Pixel::YUV420P12 => Some(12),
Pixel::YUV422P12 => Some(12),
Pixel::YUV440P12 => Some(12),
Pixel::YUV444P12 => Some(12),
Pixel::YUV420P14 => Some(14),
Pixel::YUV422P14 => Some(14),
Pixel::YUV444P14 => Some(14),
Pixel::YUV420P16 => Some(16),
Pixel::YUV422P16 => Some(16),
Pixel::YUV444P16 => Some(16),
Pixel::GBRP9 => Some(9),
Pixel::GBRP10 => Some(10),
Pixel::GBRP12 => Some(12),
Pixel::GBRP14 => Some(14),
Pixel::GBRP16 => Some(16),
Pixel::GBRAP16 => Some(16),
Pixel::BAYER_BGGR16 => Some(16),
Pixel::BAYER_RGGB16 => Some(16),
Pixel::BAYER_GBRG16 => Some(16),
Pixel::BAYER_GRBG16 => Some(16),
Pixel::YUVA420P9 => Some(9),
Pixel::YUVA422P9 => Some(9),
Pixel::YUVA444P9 => Some(9),
Pixel::YUVA420P10 => Some(10),
Pixel::YUVA422P10 => Some(10),
Pixel::YUVA444P10 => Some(10),
Pixel::YUVA420P16 => Some(16),
Pixel::YUVA422P16 => Some(16),
Pixel::YUVA444P16 => Some(16),
Pixel::XYZ12 => Some(12),
Pixel::NV20 => Some(10),
Pixel::AYUV64 => Some(16),
}
}
// Returns the number of color channels in the pixel format.
//
// Note 1: this excludes the alpha channel.
// Note 2: for bayer-like formats this represents the total number of
// photo sites in one complete tile pattern. Usually this is 4.
// Note 3: for palette-indexed formats, this is the number of channels
// in a palette color.
fn pixel_color_channel_count(f: Pixel) -> Option<usize> {
match f {
// No specific pixel format defined.
Pixel::None => None,
Pixel::VAAPI_MOCO => None,
Pixel::VAAPI_IDCT => None,
Pixel::VAAPI_VLD => None,
Pixel::DXVA2_VLD => None,
Pixel::VDPAU => None,
Pixel::QSV => None,
Pixel::MMAL => None,
Pixel::D3D11VA_VLD => None,
Pixel::CUDA => None,
Pixel::XVMC => None,
Pixel::VIDEOTOOLBOX => None,
Pixel::MEDIACODEC => None,
Pixel::D3D11 => None,
Pixel::DRM_PRIME => None,
Pixel::OPENCL => None,
Pixel::VULKAN => None,
// Defined pixel formats.
Pixel::YUV420P => Some(3),
Pixel::YUYV422 => Some(3),
Pixel::RGB24 => Some(3),
Pixel::BGR24 => Some(3),
Pixel::YUV422P => Some(3),
Pixel::YUV444P => Some(3),
Pixel::YUV410P => Some(3),
Pixel::YUV411P => Some(3),
Pixel::GRAY8 => Some(1),
Pixel::MonoWhite => Some(1),
Pixel::MonoBlack => Some(1),
Pixel::PAL8 => Some(3),
Pixel::YUVJ420P => Some(3),
Pixel::YUVJ422P => Some(3),
Pixel::YUVJ444P => Some(3),
Pixel::UYVY422 => Some(3),
Pixel::UYYVYY411 => Some(3),
Pixel::BGR8 => Some(3),
Pixel::BGR4 => Some(3),
Pixel::BGR4_BYTE => Some(3),
Pixel::RGB8 => Some(3),
Pixel::RGB4 => Some(3),
Pixel::RGB4_BYTE => Some(3),
Pixel::NV12 => Some(3),
Pixel::NV21 => Some(3),
Pixel::ARGB => Some(3),
Pixel::RGBA => Some(3),
Pixel::ABGR => Some(3),
Pixel::BGRA => Some(3),
Pixel::GRAY16BE => Some(1),
Pixel::GRAY16LE => Some(1),
Pixel::YUV440P => Some(3),
Pixel::YUVJ440P => Some(3),
Pixel::YUVA420P => Some(3),
Pixel::RGB48BE => Some(3),
Pixel::RGB48LE => Some(3),
Pixel::RGB565BE => Some(3),
Pixel::RGB565LE => Some(3),
Pixel::RGB555BE => Some(3),
Pixel::RGB555LE => Some(3),
Pixel::BGR565BE => Some(3),
Pixel::BGR565LE => Some(3),
Pixel::BGR555BE => Some(3),
Pixel::BGR555LE => Some(3),
Pixel::YUV420P16LE => Some(3),
Pixel::YUV420P16BE => Some(3),
Pixel::YUV422P16LE => Some(3),
Pixel::YUV422P16BE => Some(3),
Pixel::YUV444P16LE => Some(3),
Pixel::YUV444P16BE => Some(3),
Pixel::RGB444LE => Some(3),
Pixel::RGB444BE => Some(3),
Pixel::BGR444LE => Some(3),
Pixel::BGR444BE => Some(3),
Pixel::YA8 => Some(1),
Pixel::BGR48BE => Some(3),
Pixel::BGR48LE => Some(3),
Pixel::YUV420P9BE => Some(3),
Pixel::YUV420P9LE => Some(3),
Pixel::YUV420P10BE => Some(3),
Pixel::YUV420P10LE => Some(3),
Pixel::YUV422P10BE => Some(3),
Pixel::YUV422P10LE => Some(3),
Pixel::YUV444P9BE => Some(3),
Pixel::YUV444P9LE => Some(3),
Pixel::YUV444P10BE => Some(3),
Pixel::YUV444P10LE => Some(3),
Pixel::YUV422P9BE => Some(3),
Pixel::YUV422P9LE => Some(3),
Pixel::GBRP => Some(3),
Pixel::GBRP9BE => Some(3),
Pixel::GBRP9LE => Some(3),
Pixel::GBRP10BE => Some(3),
Pixel::GBRP10LE => Some(3),
Pixel::GBRP16BE => Some(3),
Pixel::GBRP16LE => Some(3),
Pixel::YUVA420P9BE => Some(3),
Pixel::YUVA420P9LE => Some(3),
Pixel::YUVA422P9BE => Some(3),
Pixel::YUVA422P9LE => Some(3),
Pixel::YUVA444P9BE => Some(3),
Pixel::YUVA444P9LE => Some(3),
Pixel::YUVA420P10BE => Some(3),
Pixel::YUVA420P10LE => Some(3),
Pixel::YUVA422P10BE => Some(3),
Pixel::YUVA422P10LE => Some(3),
Pixel::YUVA444P10BE => Some(3),
Pixel::YUVA444P10LE => Some(3),
Pixel::YUVA420P16BE => Some(3),
Pixel::YUVA420P16LE => Some(3),
Pixel::YUVA422P16BE => Some(3),
Pixel::YUVA422P16LE => Some(3),
Pixel::YUVA444P16BE => Some(3),
Pixel::YUVA444P16LE => Some(3),
Pixel::XYZ12LE => Some(3),
Pixel::XYZ12BE => Some(3),
Pixel::NV16 => Some(3),
Pixel::NV20LE => Some(3),
Pixel::NV20BE => Some(3),
Pixel::RGBA64BE => Some(3),
Pixel::RGBA64LE => Some(3),
Pixel::BGRA64BE => Some(3),
Pixel::BGRA64LE => Some(3),
Pixel::YVYU422 => Some(3),
Pixel::YA16BE => Some(1),
Pixel::YA16LE => Some(1),
Pixel::ZRGB => Some(3),
Pixel::RGBZ => Some(3),
Pixel::ZBGR => Some(3),
Pixel::BGRZ => Some(3),
Pixel::YUVA444P => Some(3),
Pixel::YUVA422P => Some(3),
Pixel::YUV420P12BE => Some(3),
Pixel::YUV420P12LE => Some(3),
Pixel::YUV420P14BE => Some(3),
Pixel::YUV420P14LE => Some(3),
Pixel::YUV422P12BE => Some(3),
Pixel::YUV422P12LE => Some(3),
Pixel::YUV422P14BE => Some(3),
Pixel::YUV422P14LE => Some(3),
Pixel::YUV444P12BE => Some(3),
Pixel::YUV444P12LE => Some(3),
Pixel::YUV444P14BE => Some(3),
Pixel::YUV444P14LE => Some(3),
Pixel::GBRP12BE => Some(3),
Pixel::GBRP12LE => Some(3),
Pixel::GBRP14BE => Some(3),
Pixel::GBRP14LE => Some(3),
Pixel::GBRAP => Some(3),
Pixel::GBRAP16BE => Some(3),
Pixel::GBRAP16LE => Some(3),
Pixel::YUVJ411P => Some(3),
Pixel::BAYER_BGGR8 => Some(4),
Pixel::BAYER_RGGB8 => Some(4),
Pixel::BAYER_GBRG8 => Some(4),
Pixel::BAYER_GRBG8 => Some(4),
Pixel::BAYER_BGGR16LE => Some(4),
Pixel::BAYER_BGGR16BE => Some(4),
Pixel::BAYER_RGGB16LE => Some(4),
Pixel::BAYER_RGGB16BE => Some(4),
Pixel::BAYER_GBRG16LE => Some(4),
Pixel::BAYER_GBRG16BE => Some(4),
Pixel::BAYER_GRBG16LE => Some(4),
Pixel::BAYER_GRBG16BE => Some(4),
Pixel::YUV440P10LE => Some(3),
Pixel::YUV440P10BE => Some(3),
Pixel::YUV440P12LE => Some(3),
Pixel::YUV440P12BE => Some(3),
Pixel::AYUV64LE => Some(3),
Pixel::AYUV64BE => Some(3),
Pixel::P010LE => Some(3),
Pixel::P010BE => Some(3),
Pixel::GBRAP12BE => Some(3),
Pixel::GBRAP12LE => Some(3),
Pixel::GBRAP10LE => Some(3),
Pixel::GBRAP10BE => Some(3),
Pixel::GRAY12BE => Some(1),
Pixel::GRAY12LE => Some(1),
Pixel::GRAY10BE => Some(1),
Pixel::GRAY10LE => Some(1),
Pixel::P016LE => Some(3),
Pixel::P016BE => Some(3),
Pixel::GRAY9BE => Some(1),
Pixel::GRAY9LE => Some(1),
Pixel::GBRPF32BE => Some(3),
Pixel::GBRPF32LE => Some(3),
Pixel::GBRAPF32BE => Some(3),
Pixel::GBRAPF32LE => Some(3),
Pixel::GRAY14BE => Some(1),
Pixel::GRAY14LE => Some(1),
Pixel::GRAYF32BE => Some(1),
Pixel::GRAYF32LE => Some(1),
Pixel::YUVA422P12BE => Some(3),
Pixel::YUVA422P12LE => Some(3),
Pixel::YUVA444P12BE => Some(3),
Pixel::YUVA444P12LE => Some(3),
Pixel::NV24 => Some(3),
Pixel::NV42 => Some(3),
Pixel::Y210BE => Some(3),
Pixel::Y210LE => Some(3),
Pixel::X2RGB10LE => Some(3),
Pixel::X2RGB10BE => Some(3),
// Aliases for some of the above formats, but native endian.
Pixel::RGB32 => Some(3),
Pixel::RGB32_1 => Some(3),
Pixel::BGR32 => Some(3),
Pixel::BGR32_1 => Some(3),
Pixel::ZRGB32 => Some(3),
Pixel::ZBGR32 => Some(3),
Pixel::GRAY16 => Some(1),
Pixel::YA16 => Some(1),
Pixel::RGB48 => Some(3),
Pixel::RGB565 => Some(3),
Pixel::RGB555 => Some(3),
Pixel::RGB444 => Some(3),
Pixel::BGR48 => Some(3),
Pixel::BGR565 => Some(3),
Pixel::BGR555 => Some(3),
Pixel::BGR444 => Some(3),
Pixel::YUV420P9 => Some(3),
Pixel::YUV422P9 => Some(3),
Pixel::YUV444P9 => Some(3),
Pixel::YUV420P10 => Some(3),
Pixel::YUV422P10 => Some(3),
Pixel::YUV440P10 => Some(3),
Pixel::YUV444P10 => Some(3),
Pixel::YUV420P12 => Some(3),
Pixel::YUV422P12 => Some(3),
Pixel::YUV440P12 => Some(3),
Pixel::YUV444P12 => Some(3),
Pixel::YUV420P14 => Some(3),
Pixel::YUV422P14 => Some(3),
Pixel::YUV444P14 => Some(3),
Pixel::YUV420P16 => Some(3),
Pixel::YUV422P16 => Some(3),
Pixel::YUV444P16 => Some(3),
Pixel::GBRP9 => Some(1),
Pixel::GBRP10 => Some(1),
Pixel::GBRP12 => Some(1),
Pixel::GBRP14 => Some(1),
Pixel::GBRP16 => Some(1),
Pixel::GBRAP16 => Some(1),
Pixel::BAYER_BGGR16 => Some(4),
Pixel::BAYER_RGGB16 => Some(4),
Pixel::BAYER_GBRG16 => Some(4),
Pixel::BAYER_GRBG16 => Some(4),
Pixel::YUVA420P9 => Some(3),
Pixel::YUVA422P9 => Some(3),
Pixel::YUVA444P9 => Some(3),
Pixel::YUVA420P10 => Some(3),
Pixel::YUVA422P10 => Some(3),
Pixel::YUVA444P10 => Some(3),
Pixel::YUVA420P16 => Some(3),
Pixel::YUVA422P16 => Some(3),
Pixel::YUVA444P16 => Some(3),
Pixel::XYZ12 => Some(3),
Pixel::NV20 => Some(3),
Pixel::AYUV64 => Some(3),
}
}
// Returns whether the given pixel format has an alpha channel or not.
fn pixel_has_alpha(f: Pixel) -> Option<bool> {
match f {
// No specific pixel format defined.
Pixel::None => None,
Pixel::VAAPI_MOCO => None,
Pixel::VAAPI_IDCT => None,
Pixel::VAAPI_VLD => None,
Pixel::DXVA2_VLD => None,
Pixel::VDPAU => None,
Pixel::QSV => None,
Pixel::MMAL => None,
Pixel::D3D11VA_VLD => None,
Pixel::CUDA => None,
Pixel::XVMC => None,
Pixel::VIDEOTOOLBOX => None,
Pixel::MEDIACODEC => None,
Pixel::D3D11 => None,
Pixel::DRM_PRIME => None,
Pixel::OPENCL => None,
Pixel::VULKAN => None,
// Defined pixel formats.
Pixel::YUV420P => Some(false),
Pixel::YUYV422 => Some(false),
Pixel::RGB24 => Some(false),
Pixel::BGR24 => Some(false),
Pixel::YUV422P => Some(false),
Pixel::YUV444P => Some(false),
Pixel::YUV410P => Some(false),
Pixel::YUV411P => Some(false),
Pixel::GRAY8 => Some(false),
Pixel::MonoWhite => Some(false),
Pixel::MonoBlack => Some(false),
Pixel::PAL8 => Some(false),
Pixel::YUVJ420P => Some(false),
Pixel::YUVJ422P => Some(false),
Pixel::YUVJ444P => Some(false),
Pixel::UYVY422 => Some(false),
Pixel::UYYVYY411 => Some(false),
Pixel::BGR8 => Some(false),
Pixel::BGR4 => Some(false),
Pixel::BGR4_BYTE => Some(false),
Pixel::RGB8 => Some(false),
Pixel::RGB4 => Some(false),
Pixel::RGB4_BYTE => Some(false),
Pixel::NV12 => Some(false),
Pixel::NV21 => Some(false),
Pixel::ARGB => Some(true),
Pixel::RGBA => Some(true),
Pixel::ABGR => Some(true),
Pixel::BGRA => Some(true),
Pixel::GRAY16BE => Some(false),
Pixel::GRAY16LE => Some(false),
Pixel::YUV440P => Some(false),
Pixel::YUVJ440P => Some(false),
Pixel::YUVA420P => Some(false),
Pixel::RGB48BE => Some(false),
Pixel::RGB48LE => Some(false),
Pixel::RGB565BE => Some(false),
Pixel::RGB565LE => Some(false),
Pixel::RGB555BE => Some(false),
Pixel::RGB555LE => Some(false),
Pixel::BGR565BE => Some(false),
Pixel::BGR565LE => Some(false),
Pixel::BGR555BE => Some(false),
Pixel::BGR555LE => Some(false),
Pixel::YUV420P16LE => Some(false),
Pixel::YUV420P16BE => Some(false),
Pixel::YUV422P16LE => Some(false),
Pixel::YUV422P16BE => Some(false),
Pixel::YUV444P16LE => Some(false),
Pixel::YUV444P16BE => Some(false),
Pixel::RGB444LE => Some(false),
Pixel::RGB444BE => Some(false),
Pixel::BGR444LE => Some(false),
Pixel::BGR444BE => Some(false),
Pixel::YA8 => Some(true),
Pixel::BGR48BE => Some(false),
Pixel::BGR48LE => Some(false),
Pixel::YUV420P9BE => Some(false),
Pixel::YUV420P9LE => Some(false),
Pixel::YUV420P10BE => Some(false),
Pixel::YUV420P10LE => Some(false),
Pixel::YUV422P10BE => Some(false),
Pixel::YUV422P10LE => Some(false),
Pixel::YUV444P9BE => Some(false),
Pixel::YUV444P9LE => Some(false),
Pixel::YUV444P10BE => Some(false),
Pixel::YUV444P10LE => Some(false),
Pixel::YUV422P9BE => Some(false),
Pixel::YUV422P9LE => Some(false),
Pixel::GBRP => Some(false),
Pixel::GBRP9BE => Some(false),
Pixel::GBRP9LE => Some(false),
Pixel::GBRP10BE => Some(false),
Pixel::GBRP10LE => Some(false),
Pixel::GBRP16BE => Some(false),
Pixel::GBRP16LE => Some(false),
Pixel::YUVA420P9BE => Some(true),
Pixel::YUVA420P9LE => Some(true),
Pixel::YUVA422P9BE => Some(true),
Pixel::YUVA422P9LE => Some(true),
Pixel::YUVA444P9BE => Some(true),
Pixel::YUVA444P9LE => Some(true),
Pixel::YUVA420P10BE => Some(true),
Pixel::YUVA420P10LE => Some(true),
Pixel::YUVA422P10BE => Some(true),
Pixel::YUVA422P10LE => Some(true),
Pixel::YUVA444P10BE => Some(true),
Pixel::YUVA444P10LE => Some(true),
Pixel::YUVA420P16BE => Some(true),
Pixel::YUVA420P16LE => Some(true),
Pixel::YUVA422P16BE => Some(true),
Pixel::YUVA422P16LE => Some(true),
Pixel::YUVA444P16BE => Some(true),
Pixel::YUVA444P16LE => Some(true),
Pixel::XYZ12LE => Some(false),
Pixel::XYZ12BE => Some(false),
Pixel::NV16 => Some(false),
Pixel::NV20LE => Some(false),
Pixel::NV20BE => Some(false),
Pixel::RGBA64BE => Some(true),
Pixel::RGBA64LE => Some(true),
Pixel::BGRA64BE => Some(true),
Pixel::BGRA64LE => Some(true),
Pixel::YVYU422 => Some(false),
Pixel::YA16BE => Some(true),
Pixel::YA16LE => Some(true),
Pixel::ZRGB => Some(false),
Pixel::RGBZ => Some(false),
Pixel::ZBGR => Some(false),
Pixel::BGRZ => Some(false),
Pixel::YUVA444P => Some(true),
Pixel::YUVA422P => Some(true),
Pixel::YUV420P12BE => Some(false),
Pixel::YUV420P12LE => Some(false),
Pixel::YUV420P14BE => Some(false),
Pixel::YUV420P14LE => Some(false),
Pixel::YUV422P12BE => Some(false),
Pixel::YUV422P12LE => Some(false),
Pixel::YUV422P14BE => Some(false),
Pixel::YUV422P14LE => Some(false),
Pixel::YUV444P12BE => Some(false),
Pixel::YUV444P12LE => Some(false),
Pixel::YUV444P14BE => Some(false),
Pixel::YUV444P14LE => Some(false),
Pixel::GBRP12BE => Some(false),
Pixel::GBRP12LE => Some(false),
Pixel::GBRP14BE => Some(false),
Pixel::GBRP14LE => Some(false),
Pixel::GBRAP => Some(true),
Pixel::GBRAP16BE => Some(true),
Pixel::GBRAP16LE => Some(true),
Pixel::YUVJ411P => Some(false),
Pixel::BAYER_BGGR8 => Some(false),
Pixel::BAYER_RGGB8 => Some(false),
Pixel::BAYER_GBRG8 => Some(false),
Pixel::BAYER_GRBG8 => Some(false),
Pixel::BAYER_BGGR16LE => Some(false),
Pixel::BAYER_BGGR16BE => Some(false),
Pixel::BAYER_RGGB16LE => Some(false),
Pixel::BAYER_RGGB16BE => Some(false),
Pixel::BAYER_GBRG16LE => Some(false),
Pixel::BAYER_GBRG16BE => Some(false),
Pixel::BAYER_GRBG16LE => Some(false),
Pixel::BAYER_GRBG16BE => Some(false),
Pixel::YUV440P10LE => Some(false),
Pixel::YUV440P10BE => Some(false),
Pixel::YUV440P12LE => Some(false),
Pixel::YUV440P12BE => Some(false),
Pixel::AYUV64LE => Some(true),
Pixel::AYUV64BE => Some(true),
Pixel::P010LE => Some(false),
Pixel::P010BE => Some(false),
Pixel::GBRAP12BE => Some(true),
Pixel::GBRAP12LE => Some(true),
Pixel::GBRAP10LE => Some(true),
Pixel::GBRAP10BE => Some(true),
Pixel::GRAY12BE => Some(false),
Pixel::GRAY12LE => Some(false),
Pixel::GRAY10BE => Some(false),
Pixel::GRAY10LE => Some(false),
Pixel::P016LE => Some(false),
Pixel::P016BE => Some(false),
Pixel::GRAY9BE => Some(false),
Pixel::GRAY9LE => Some(false),
Pixel::GBRPF32BE => Some(false),
Pixel::GBRPF32LE => Some(false),
Pixel::GBRAPF32BE => Some(true),
Pixel::GBRAPF32LE => Some(true),
Pixel::GRAY14BE => Some(false),
Pixel::GRAY14LE => Some(false),
Pixel::GRAYF32BE => Some(false),
Pixel::GRAYF32LE => Some(false),
Pixel::YUVA422P12BE => Some(true),
Pixel::YUVA422P12LE => Some(true),
Pixel::YUVA444P12BE => Some(true),
Pixel::YUVA444P12LE => Some(true),
Pixel::NV24 => Some(false),
Pixel::NV42 => Some(false),
Pixel::Y210BE => Some(false),
Pixel::Y210LE => Some(false),
Pixel::X2RGB10LE => Some(false),
Pixel::X2RGB10BE => Some(false),
// Aliases for some of the above formats, but native endian.
Pixel::RGB32 => Some(false),
Pixel::RGB32_1 => Some(false),
Pixel::BGR32 => Some(false),
Pixel::BGR32_1 => Some(false),
Pixel::ZRGB32 => Some(false),
Pixel::ZBGR32 => Some(false),
Pixel::GRAY16 => Some(false),
Pixel::YA16 => Some(true),
Pixel::RGB48 => Some(false),
Pixel::RGB565 => Some(false),
Pixel::RGB555 => Some(false),
Pixel::RGB444 => Some(false),
Pixel::BGR48 => Some(false),
Pixel::BGR565 => Some(false),
Pixel::BGR555 => Some(false),
Pixel::BGR444 => Some(false),
Pixel::YUV420P9 => Some(false),
Pixel::YUV422P9 => Some(false),
Pixel::YUV444P9 => Some(false),
Pixel::YUV420P10 => Some(false),
Pixel::YUV422P10 => Some(false),
Pixel::YUV440P10 => Some(false),
Pixel::YUV444P10 => Some(false),
Pixel::YUV420P12 => Some(false),
Pixel::YUV422P12 => Some(false),
Pixel::YUV440P12 => Some(false),
Pixel::YUV444P12 => Some(false),
Pixel::YUV420P14 => Some(false),
Pixel::YUV422P14 => Some(false),
Pixel::YUV444P14 => Some(false),
Pixel::YUV420P16 => Some(false),
Pixel::YUV422P16 => Some(false),
Pixel::YUV444P16 => Some(false),
Pixel::GBRP9 => Some(false),
Pixel::GBRP10 => Some(false),
Pixel::GBRP12 => Some(false),
Pixel::GBRP14 => Some(false),
Pixel::GBRP16 => Some(false),
Pixel::GBRAP16 => Some(true),
Pixel::BAYER_BGGR16 => Some(false),
Pixel::BAYER_RGGB16 => Some(false),
Pixel::BAYER_GBRG16 => Some(false),
Pixel::BAYER_GRBG16 => Some(false),
Pixel::YUVA420P9 => Some(true),
Pixel::YUVA422P9 => Some(true),
Pixel::YUVA444P9 => Some(true),
Pixel::YUVA420P10 => Some(true),
Pixel::YUVA422P10 => Some(true),
Pixel::YUVA444P10 => Some(true),
Pixel::YUVA420P16 => Some(true),
Pixel::YUVA422P16 => Some(true),
Pixel::YUVA444P16 => Some(true),
Pixel::XYZ12 => Some(false),
Pixel::NV20 => Some(false),
Pixel::AYUV64 => Some(true),
} }
} }