#[cfg(not(feature = "video"))]
compile_error!("enable the `video` feature on mediaway-encoder");
use crate::EncodeError;
use crate::{VideoEncoder, VideoEncoderConfig};
use mediaway_common::VideoFrame;
use mediaway_common::{Bytes, Packet, StreamInfo};
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
mod linux;
pub struct AmfVideoEncoder {
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
inner: Option<linux::AmfSession>,
#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
_priv: (),
}
impl AmfVideoEncoder {
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
pub fn open(config: &VideoEncoderConfig) -> Result<Self, EncodeError> {
let inner = linux::AmfSession::open(config)?;
Ok(Self { inner: Some(inner) })
}
#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
pub const fn open(_config: &VideoEncoderConfig) -> Result<Self, EncodeError> {
Err(EncodeError::Unsupported)
}
}
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
impl VideoEncoder for AmfVideoEncoder {
fn stream_info(&self) -> &StreamInfo {
#[allow(
clippy::option_if_let_else,
reason = "map_or_else forces 'static vs 'self lifetime clash"
)]
if let Some(e) = self.inner.as_ref() {
e.stream_info()
} else {
closed_stream_info()
}
}
fn push_frame(&mut self, frame: &VideoFrame) -> Result<(), EncodeError> {
self.inner
.as_mut()
.ok_or(EncodeError::Closed)?
.push_frame(frame)
}
fn poll_packet(&mut self) -> Result<Option<Packet>, EncodeError> {
self.inner
.as_mut()
.ok_or(EncodeError::Closed)?
.poll_packet()
}
fn flush(&mut self) -> Result<(), EncodeError> {
self.inner.as_mut().ok_or(EncodeError::Closed)?.flush()
}
fn set_bitrate(&mut self, bitrate_bps: u32) -> Result<(), EncodeError> {
self.inner
.as_mut()
.ok_or(EncodeError::Closed)?
.set_bitrate(bitrate_bps)
}
}
#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
impl VideoEncoder for AmfVideoEncoder {
fn stream_info(&self) -> &StreamInfo {
closed_stream_info()
}
fn push_frame(&mut self, _frame: &VideoFrame) -> Result<(), EncodeError> {
Err(EncodeError::Unsupported)
}
fn poll_packet(&mut self) -> Result<Option<Packet>, EncodeError> {
Ok(None)
}
fn flush(&mut self) -> Result<(), EncodeError> {
Err(EncodeError::Unsupported)
}
}
fn closed_stream_info() -> &'static StreamInfo {
use std::sync::OnceLock;
static INFO: OnceLock<StreamInfo> = OnceLock::new();
INFO.get_or_init(|| StreamInfo::Video {
id: 0,
codec: mediaway_common::CodecKind::H264,
time_base: mediaway_common::Rational::new(1, 30),
geometry: mediaway_common::VideoGeometry {
width: 0,
height: 0,
},
extra_data: Bytes::new(),
})
}
#[cfg(all(test, target_os = "linux", target_arch = "x86_64"))]
#[path = "lib_tests.rs"]
mod tests;