Skip to content
Snippets Groups Projects
Commit 07356602 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

even more improvements

parent 3ba228ad
Branches
No related tags found
No related merge requests found
...@@ -60,7 +60,7 @@ impl<'a> AVFormatContext { ...@@ -60,7 +60,7 @@ impl<'a> AVFormatContext {
} }
.iter() .iter()
.map(|stream| { .map(|stream| {
AVStream::new(unsafe { (*stream).as_mut() }.expect("not null"), self) AVStream::new(unsafe { (*stream).as_mut() }.expect("not null"), &self)
}) })
.collect(); .collect();
} }
...@@ -264,30 +264,30 @@ impl<'a> AVStream<'a> { ...@@ -264,30 +264,30 @@ impl<'a> AVStream<'a> {
) )
} }
pub fn duration(self: &AVStream<'a>) -> std::time::Duration { pub fn duration(&self) -> std::time::Duration {
self.timestamp(self.base.duration) self.timestamp(self.base.duration)
} }
pub fn frame_count(self: &AVStream<'a>) -> i64 { pub fn frame_count(&self) -> i64 {
self.base.nb_frames self.base.nb_frames
} }
pub fn discard(self: &AVStream<'a>) -> Option<AVDiscard> { pub fn discard(&self) -> Option<AVDiscard> {
AVDiscard::from_i32(self.base.discard) AVDiscard::from_i32(self.base.discard)
} }
pub fn set_discard(self: &mut AVStream<'a>, value: AVDiscard) { pub fn set_discard(&mut self, value: AVDiscard) {
self.base.discard = value as ffi::AVDiscard; self.base.discard = value as ffi::AVDiscard;
} }
pub fn sample_aspect_ratio(self: &AVStream<'a>) -> Fraction { pub fn sample_aspect_ratio(&self) -> Fraction {
Fraction::new( Fraction::new(
self.base.sample_aspect_ratio.num as u32, self.base.sample_aspect_ratio.num as u32,
self.base.sample_aspect_ratio.den as u32, self.base.sample_aspect_ratio.den as u32,
) )
} }
pub fn codec_parameters(self: &AVStream<'a>) -> AVCodecParameters { pub fn codec_parameters(&self) -> AVCodecParameters {
AVCodecParameters::new(unsafe { self.base.codecpar.as_mut() }.expect("not null"), self) AVCodecParameters::new(unsafe { self.base.codecpar.as_mut() }.expect("not null"), self)
} }
} }
...@@ -307,15 +307,15 @@ impl<'a> AVCodecParameters<'a> { ...@@ -307,15 +307,15 @@ impl<'a> AVCodecParameters<'a> {
self.base self.base
} }
pub fn codec_type(self: &AVCodecParameters<'a>) -> AVMediaType { pub fn codec_type(&self) -> AVMediaType {
AVMediaType::from_i32(self.base.codec_type).unwrap_or(AVMediaType::Unknown) AVMediaType::from_i32(self.base.codec_type).unwrap_or(AVMediaType::Unknown)
} }
pub fn codec_id(self: &AVCodecParameters<'a>) -> Option<AVCodecID> { pub fn codec_id(&self) -> Option<AVCodecID> {
AVCodecID::from_u32(self.base.codec_id) AVCodecID::from_u32(self.base.codec_id)
} }
pub fn find_decoder(self: &AVCodecParameters<'a>) -> AVCodec { pub fn find_decoder(&self) -> AVCodec {
AVCodec::new( AVCodec::new(
unsafe { ffi::avcodec_find_decoder(self.base.codec_id).as_mut() }.expect("Decoder not found"), unsafe { ffi::avcodec_find_decoder(self.base.codec_id).as_mut() }.expect("Decoder not found"),
self, self,
...@@ -342,3 +342,76 @@ impl<'a> AVCodec<'a> { ...@@ -342,3 +342,76 @@ impl<'a> AVCodec<'a> {
String::from(unsafe { std::ffi::CStr::from_ptr(self.base.name) }.to_str().unwrap()) String::from(unsafe { std::ffi::CStr::from_ptr(self.base.name) }.to_str().unwrap())
} }
} }
pub struct AVCodecContext {
base: *mut ffi::AVCodecContext,
}
impl AVCodecContext {
pub fn new(codec: &AVCodec) -> Result<Self, failure::Error> {
let base = unsafe { ffi::avcodec_alloc_context3(codec.base) };
if base.is_null() {
bail!("avcodec_alloc_context3() failed");
}
Ok(AVCodecContext { base })
}
// TODO: Just for testing
pub unsafe fn raw(&self) -> *mut ffi::AVCodecContext {
self.base
}
pub fn skip_loop_filter(&self) -> Option<AVDiscard> {
let base = unsafe { self.base.as_ref() }.expect("not null");
AVDiscard::from_i32(base.skip_loop_filter)
}
pub fn set_skip_loop_filter(&mut self, value: AVDiscard) {
let base = unsafe { self.base.as_mut() }.expect("not null");
base.skip_loop_filter = value as ffi::AVDiscard
}
pub fn skip_idct(&self) -> Option<AVDiscard> {
let base = unsafe { self.base.as_ref() }.expect("not null");
AVDiscard::from_i32(base.skip_idct)
}
pub fn set_skip_idct(&mut self, value: AVDiscard) {
let base = unsafe { self.base.as_mut() }.expect("not null");
base.skip_idct = value as ffi::AVDiscard
}
pub fn skip_frame(&self) -> Option<AVDiscard> {
let base = unsafe { self.base.as_ref() }.expect("not null");
AVDiscard::from_i32(base.skip_frame)
}
pub fn set_skip_frame(&mut self, value: AVDiscard) {
let base = unsafe { self.base.as_mut() }.expect("not null");
base.skip_frame = value as ffi::AVDiscard
}
pub fn set_parameters(&mut self, params: &AVCodecParameters) {
unsafe {
ffi::avcodec_parameters_to_context(self.base, params.base);
}
}
pub fn open(&mut self, codec: &AVCodec) {
unsafe {
ffi::avcodec_open2(self.base, codec.base, std::ptr::null_mut());
}
}
}
impl Drop for AVCodecContext {
fn drop(&mut self) {
unsafe { ffi::avcodec_free_context(&mut self.base) }
}
}
\ No newline at end of file
...@@ -37,27 +37,22 @@ fn main() -> Result<(), std::io::Error> { ...@@ -37,27 +37,22 @@ fn main() -> Result<(), std::io::Error> {
panic!("Could not init output frame: {:?}", error) panic!("Could not init output frame: {:?}", error)
}); });
match codec_parameters.codec_type() { if codec_parameters.codec_type() == AVMediaType::Video {
AVMediaType::Video => { let mut codec_context = AVCodecContext::new(&local_codec).unwrap_or_else(|error| {
panic!("Could not init codec context: {:?}", error)
// TODO: HERE BE DRAGONS });
codec_context.set_parameters(&codec_parameters);
let avc_ctx: &mut ffi::AVCodecContext = unsafe { codec_context.open(&local_codec);
ffi::avcodec_alloc_context3(local_codec.as_ref()).as_mut()
}.expect("not null");
avc_ctx.skip_loop_filter = ffi::AVDiscard_AVDISCARD_NONKEY;
avc_ctx.skip_idct = ffi::AVDiscard_AVDISCARD_NONKEY;
avc_ctx.skip_frame = ffi::AVDiscard_AVDISCARD_NONKEY;
unsafe { codec_context.set_skip_loop_filter(AVDiscard::NonKey);
ffi::avcodec_parameters_to_context(avc_ctx, codec_parameters.as_ref()); codec_context.set_skip_idct(AVDiscard::NonKey);
ffi::avcodec_open2(avc_ctx, local_codec.as_ref(), std::ptr::null_mut()); codec_context.set_skip_frame(AVDiscard::NonKey);
}
// TODO: HERE BE DRAGONS
let packet: &mut ffi::AVPacket = unsafe { let packet: &mut ffi::AVPacket = unsafe {
ffi::av_packet_alloc().as_mut() ffi::av_packet_alloc().as_mut()
}.expect("not null"); }.expect("not null");
// TODO: END DRAGONS
let mut frame = AVFrame::new().unwrap_or_else(|error| { let mut frame = AVFrame::new().unwrap_or_else(|error| {
panic!("Could not create input frame: {:?}", error) panic!("Could not create input frame: {:?}", error)
...@@ -68,15 +63,13 @@ fn main() -> Result<(), std::io::Error> { ...@@ -68,15 +63,13 @@ fn main() -> Result<(), std::io::Error> {
println!("Time: {:#?}", before.elapsed().unwrap()); println!("Time: {:#?}", before.elapsed().unwrap());
before = std::time::SystemTime::now(); before = std::time::SystemTime::now();
let mut sws_context: *mut ffi::SwsContext = std::ptr::null_mut(); //TODO: HERE BE DRAGONS
while unsafe { ffi::av_read_frame(avformat_context.raw(), packet) } >= 0 && i < 10 { while unsafe { ffi::av_read_frame(avformat_context.raw(), packet) } >= 0 && i < 10 {
if packet.stream_index == stream.index() { if packet.stream_index == stream.index() {
unsafe { unsafe { ffi::avcodec_send_packet(codec_context.raw(), packet) };
ffi::avcodec_send_packet(avc_ctx, packet); while unsafe { ffi::avcodec_receive_frame(codec_context.raw(), frame.as_mut()) } >= 0 {
} // TODO: END DRAGONS
while unsafe { ffi::avcodec_receive_frame(avc_ctx, frame.as_mut()) } >= 0 {
println!( println!(
"Frame {}: {:?} @ {}", "Frame {}: {:?} @ {}",
frame.coded_picture_number(), frame.coded_picture_number(),
...@@ -86,22 +79,21 @@ fn main() -> Result<(), std::io::Error> { ...@@ -86,22 +79,21 @@ fn main() -> Result<(), std::io::Error> {
println!("Reading Time: {:#?}", before.elapsed().unwrap()); println!("Reading Time: {:#?}", before.elapsed().unwrap());
before = std::time::SystemTime::now(); before = std::time::SystemTime::now();
if sws_context.is_null() { // TODO: HERE BE DRAGONS
sws_context = unsafe { let sws_context = unsafe {
ffi::sws_getContext( ffi::sws_getContext(
frame.width(), frame.width(),
frame.height(), frame.height(),
frame.format() as ffi::AVPixelFormat, frame.format() as ffi::AVPixelFormat,
160, output_frame.width(),
90, output_frame.height(),
ffi::AVPixelFormat_AV_PIX_FMT_RGB24, output_frame.format() as ffi::AVPixelFormat,
ffi::SWS_FAST_BILINEAR as i32, ffi::SWS_FAST_BILINEAR as i32,
std::ptr::null_mut(), std::ptr::null_mut(),
std::ptr::null_mut(), std::ptr::null_mut(),
std::ptr::null(), std::ptr::null(),
).as_mut() ).as_mut()
}.expect("not null"); }.expect("not null");
}
let success = unsafe { let success = unsafe {
ffi::sws_scale( ffi::sws_scale(
...@@ -114,6 +106,7 @@ fn main() -> Result<(), std::io::Error> { ...@@ -114,6 +106,7 @@ fn main() -> Result<(), std::io::Error> {
output_frame.linesize().as_ptr(), output_frame.linesize().as_ptr(),
) )
}; };
// TODO: END DRAGONS
println!("success: {}", success); println!("success: {}", success);
println!("Processing Time: {:#?}", before.elapsed().unwrap()); println!("Processing Time: {:#?}", before.elapsed().unwrap());
...@@ -137,8 +130,6 @@ fn main() -> Result<(), std::io::Error> { ...@@ -137,8 +130,6 @@ fn main() -> Result<(), std::io::Error> {
} }
} }
} }
_ => {}
}
} }
Ok(()) Ok(())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment