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, 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 { 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(()) } }