From a33d733f6dbb0df0f14c80183e7e974557c35f51 Mon Sep 17 00:00:00 2001 From: Janne Mareike Koschinski <janne@kuschku.de> Date: Sun, 23 Feb 2020 15:55:31 +0100 Subject: [PATCH] Improve safety yet again --- src/ffmpeg_api/api.rs | 60 +++++++++++++++---------------------------- src/main.rs | 17 ++++-------- 2 files changed, 25 insertions(+), 52 deletions(-) diff --git a/src/ffmpeg_api/api.rs b/src/ffmpeg_api/api.rs index 52ccc88..de5e47e 100644 --- a/src/ffmpeg_api/api.rs +++ b/src/ffmpeg_api/api.rs @@ -6,17 +6,6 @@ use fraction::Fraction; use crate::ffmpeg_api::enums::*; -// TODO: Use proper errors (with struct etc) for this -enum_from_primitive! { - #[derive(Debug, Copy, Clone, PartialEq)] - #[repr(i32)] - pub enum AVErrorKind { - Unknown = ffi::AVERROR_EXPERIMENTAL, - InputChanged = ffi::AVERROR_INPUT_CHANGED, - OutputChanged = ffi::AVERROR_OUTPUT_CHANGED - } -} - pub struct AVFormatContext { base: *mut ffi::AVFormatContext, } @@ -30,11 +19,6 @@ impl<'a> AVFormatContext { Ok(AVFormatContext { base }) } - // TODO: Just for testing - pub unsafe fn raw(&self) -> *mut ffi::AVFormatContext { - self.base - } - pub fn open_input(&mut self, path: &str) -> Result<(), failure::Error> { match unsafe { ffi::avformat_open_input( @@ -64,6 +48,13 @@ impl<'a> AVFormatContext { }) .collect(); } + + pub fn read_frame(&/*TODO:mut*/ self, packet: &mut AVPacket) -> Result<(), failure::Error> { + match unsafe { ffi::av_read_frame(self.base, packet.base) } { + 0 => Ok(()), + errno => Err(failure::format_err!("Error while decoding frame: {}", errno)) + } + } } impl Drop for AVFormatContext { @@ -116,11 +107,6 @@ impl AVPacket { Ok(AVPacket { base }) } - // TODO: Just for testing - pub unsafe fn as_mut(&mut self) -> &mut ffi::AVPacket { - self.base.as_mut().expect("not null") - } - pub fn pts(&self) -> i64 { let base = unsafe { self.base.as_ref() }.expect("not null"); @@ -160,12 +146,7 @@ impl AVFrame { Ok(AVFrame { base, buffer: AVBuffer::empty() }) } - // TODO: Just for testing - pub unsafe fn as_mut(&mut self) -> &mut ffi::AVFrame { - self.base.as_mut().expect("not null") - } - - pub fn init(&mut self, width: i32, height: i32, format: AVPixelFormat) -> Result<(), failure::Error>{ + pub fn init(&mut self, width: i32, height: i32, format: AVPixelFormat) -> Result<(), failure::Error> { let mut base = unsafe { self.base.as_mut() }.expect("not null"); base.width = width; @@ -345,11 +326,6 @@ impl<'a> AVCodecParameters<'a> { return AVCodecParameters { base, phantom: PhantomData }; } - // TODO: Just for testing - pub unsafe fn as_ref(&self) -> &ffi::AVCodecParameters { - self.base - } - pub fn codec_type(&self) -> AVMediaType { AVMediaType::from_i32(self.base.codec_type).unwrap_or(AVMediaType::Unknown) } @@ -376,11 +352,6 @@ impl<'a> AVCodec<'a> { return AVCodec { base, phantom: PhantomData }; } - // TODO: Just for testing - pub unsafe fn as_ref(&self) -> &ffi::AVCodec { - self.base - } - pub fn name(self: &AVCodec<'a>) -> std::string::String { String::from(unsafe { std::ffi::CStr::from_ptr(self.base.name) }.to_str().unwrap()) } @@ -399,9 +370,18 @@ impl AVCodecContext { Ok(AVCodecContext { base }) } - // TODO: Just for testing - pub unsafe fn raw(&self) -> *mut ffi::AVCodecContext { - self.base + pub fn in_packet(&mut self, packet: &mut AVPacket) -> Result<(), failure::Error> { + match unsafe { ffi::avcodec_send_packet(self.base, packet.base) } { + 0 => Ok(()), + errno => Err(failure::format_err!("Error while loading paclet: {}", errno)) + } + } + + pub fn out_frame(&mut self, frame: &mut AVFrame) -> Result<(), failure::Error> { + match unsafe { ffi::avcodec_receive_frame(self.base, frame.base) } { + 0 => Ok(()), + errno => Err(failure::format_err!("Error while decoding frame: {}", errno)) + } } pub fn skip_loop_filter(&self) -> Option<AVDiscard> { diff --git a/src/main.rs b/src/main.rs index 3dcc9b5..5a6acb0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ -use ffmpeg_dev::sys as ffi; - pub(crate) mod ffmpeg_api; use crate::ffmpeg_api::enums::*; @@ -63,17 +61,12 @@ fn main() -> Result<(), std::io::Error> { let mut scale_context = SwsContext::new(); - //TODO: HERE BE DRAGONS - while unsafe { ffi::av_read_frame(avformat_context.raw(), packet.as_mut()) } >= 0 && i < 16 { - // TODO: END DRAGONS - + while avformat_context.read_frame(&mut packet).is_ok() && i < 16 { if packet.stream_index() == stream.index() { - - //TODO: HERE BE DRAGONS - unsafe { ffi::avcodec_send_packet(codec_context.raw(), packet.as_mut()) }; - while unsafe { ffi::avcodec_receive_frame(codec_context.raw(), frame.as_mut()) } >= 0 { - // TODO: END DRAGONS - + codec_context.in_packet(&mut packet).unwrap_or_else(|error| { + panic!("Could not load packet: {:?}", error) + }); + while codec_context.out_frame(&mut frame).is_ok() { println!( "Frame {}: {:?} @ {}", frame.coded_picture_number(), -- GitLab