use crate::{ffi, shared::PointerUpgrade};
use std::{ffi::CStr, ops::Deref, ptr::NonNull};
pub use ffi::AVComponentDescriptor;
pub struct AVPixFmtDescriptorRef(NonNull<ffi::AVPixFmtDescriptor>);
impl Deref for AVPixFmtDescriptorRef {
type Target = ffi::AVPixFmtDescriptor;
fn deref(&self) -> &Self::Target {
unsafe { self.0.as_ref() }
}
}
impl AVPixFmtDescriptorRef {
pub fn get(pix_fmt: i32) -> Option<Self> {
unsafe { ffi::av_pix_fmt_desc_get(pix_fmt).upgrade().map(Self) }
}
pub fn next(&self) -> Option<Self> {
unsafe {
ffi::av_pix_fmt_desc_next(self.0.as_ptr())
.upgrade()
.map(Self)
}
}
pub fn get_id(&self) -> i32 {
unsafe { ffi::av_pix_fmt_desc_get_id(self.0.as_ptr()) }
}
pub fn name(&self) -> &CStr {
let name = self.name.upgrade().unwrap();
unsafe { CStr::from_ptr(name.as_ptr()) }
}
pub fn alias(&self) -> Option<&CStr> {
self.alias
.upgrade()
.map(|x| unsafe { CStr::from_ptr(x.as_ptr()) })
}
}
pub fn get_pix_fmt_name(pix_fmt: ffi::AVPixelFormat) -> Option<&'static CStr> {
unsafe {
ffi::av_get_pix_fmt_name(pix_fmt)
.upgrade()
.map(|x| CStr::from_ptr(x.as_ptr()))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_pix_fmt_getter() {
let pix_fmt_desc = AVPixFmtDescriptorRef::get(ffi::AV_PIX_FMT_YUV420P).unwrap();
assert_eq!(pix_fmt_desc.name(), c"yuv420p");
assert_eq!(pix_fmt_desc.alias(), None);
assert_eq!(pix_fmt_desc.nb_components, 3);
assert_eq!(pix_fmt_desc.log2_chroma_w, 1);
assert_eq!(pix_fmt_desc.log2_chroma_h, 1);
assert_eq!(pix_fmt_desc.comp[0].plane, 0);
assert_eq!(pix_fmt_desc.comp[1].plane, 1);
assert_eq!(pix_fmt_desc.comp[2].plane, 2);
assert_eq!(pix_fmt_desc.comp[0].step, 1);
assert_eq!(pix_fmt_desc.comp[1].step, 1);
assert_eq!(pix_fmt_desc.comp[2].step, 1);
assert_eq!(pix_fmt_desc.comp[0].offset, 0);
assert_eq!(pix_fmt_desc.comp[1].offset, 0);
assert_eq!(pix_fmt_desc.comp[2].offset, 0);
assert_eq!(pix_fmt_desc.comp[0].depth, 8);
assert_eq!(pix_fmt_desc.comp[1].depth, 8);
assert_eq!(pix_fmt_desc.comp[2].depth, 8);
let pix_fmt_desc = AVPixFmtDescriptorRef::get(ffi::AV_PIX_FMT_GRAY9LE).unwrap();
assert_eq!(pix_fmt_desc.name(), c"gray9le");
assert_eq!(pix_fmt_desc.alias(), Some(c"y9le"));
}
#[test]
fn test_pix_fmt_desc_next() {
let pix_fmt_desc = AVPixFmtDescriptorRef::get(ffi::AV_PIX_FMT_GRAYF32BE).unwrap();
assert_eq!(pix_fmt_desc.name(), c"grayf32be");
assert_eq!(pix_fmt_desc.alias(), Some(c"yf32be"));
let next = pix_fmt_desc.next().unwrap();
assert_eq!(next.name(), c"grayf32le");
assert_eq!(next.alias(), Some(c"yf32le"));
}
#[test]
fn test_pix_fmt_get_id() {
let pix_fmt = ffi::AV_PIX_FMT_YUVA444P12LE;
let pix_fmt_desc = AVPixFmtDescriptorRef::get(pix_fmt).unwrap();
assert_eq!(pix_fmt_desc.get_id(), pix_fmt);
}
#[test]
fn test_get_pix_fmt_name() {
let s = get_pix_fmt_name(ffi::AV_PIX_FMT_YUV420P).unwrap();
assert_eq!(s, c"yuv420p");
assert!(get_pix_fmt_name(ffi::AV_PIX_FMT_NONE).is_none());
}
}