You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.6 KiB
Rust

use crate::av::as_ptr::AsMutPtr;
use crate::av::frame::Frame;
use crate::av::packet::Packet;
use crate::av::stream::Stream;
use crate::av::xcoder::{process_return, XCoder};
use crate::av::{decoder_from_name, verify_response};
use crate::av_err2str;
use ffmpeg_sys_next::{
avcodec_parameters_to_context, avcodec_receive_frame, avcodec_send_packet, AVCodecContext,
};
#[derive(Copy, Clone)]
pub struct Decoder(pub *mut AVCodecContext);
impl Decoder {
pub fn send_packet(&self, packet: &Packet) -> Result<(), String> {
verify_response("Failed sending packet to decoder", unsafe {
avcodec_send_packet(self.0, packet.as_mut_ptr())
})
.and(Ok(()))
}
pub fn read_frame(&self) -> Result<Option<Frame>, String> {
let frame = Frame::alloc();
if !process_return("Failed reading frame from decoder", unsafe {
avcodec_receive_frame(self.as_mut_ptr(), frame.as_mut_ptr())
})? {
Ok(None)
} else {
Ok(Some(frame))
}
}
}
impl XCoder for Decoder {
fn from_name(name: &str) -> Option<Self> {
decoder_from_name(name).map(|codec| Decoder(codec))
}
fn as_mut_ptr(&self) -> *mut AVCodecContext {
self.0
}
fn configure(&self, stream: &Stream) -> Result<(), String> {
let resp =
unsafe { avcodec_parameters_to_context(self.as_mut_ptr(), (*stream.0).codecpar) };
if resp < 0 {
return Err(format!(
"Failed configuring decoder from stream (code {}: {})",
resp,
av_err2str(resp)
));
}
Ok(())
}
}