This commit is contained in:
2023-06-29 11:56:43 -06:00
commit 29e6b0c11b
6 changed files with 476 additions and 0 deletions

71
src/main.rs Normal file
View File

@@ -0,0 +1,71 @@
extern crate ffmpeg_next as ffmpeg;
use anyhow::Error;
use ffmpeg::format::{input, Pixel};
use ffmpeg::media::Type;
use ffmpeg::software::scaling::{context::Context, flag::Flags};
use ffmpeg::util::frame::video::Video;
use std::path::Path;
mod test;
fn main() -> Result<(), Error> {
// instantiate ffmpeg
ffmpeg::init()?;
// read the input file
if let Ok(mut ictx) = input(&Path::new("input")) {
let input = ictx
.streams()
.best(Type::Video)
.ok_or(ffmpeg::Error::StreamNotFound)?;
let video_stream_index = input.index();
let context_decoder = ffmpeg::codec::context::Context::from_parameters(input.parameters())?;
// Ctx's video decoder
let mut decoder = context_decoder.decoder().video()?;
let mut scaler = Context::get(
decoder.format(),
decoder.width(),
decoder.height(),
Pixel::RGB24,
decoder.width(),
decoder.height(),
Flags::BILINEAR,
)?;
// closure
let mut receive_and_process_decoded_frames = |decoder: &mut ffmpeg::decoder::Video| -> Result<(), Error> {
// get empty frame
let mut decoded = Video::empty();
// recieve next frame into decoded
while decoder.receive_frame(&mut decoded).is_ok() {
// get another empty frame
let mut rgb_frame = Video::empty();
// scale image? Not sure what this does bit it doesn't work without it.
scaler.run(&decoded, &mut rgb_frame)?;
// test::print_raw(&rgb_frame.data(0));
// test::print_square(&rgb_frame.data(0), rgb_frame.width() as usize);
test::print_square(&rgb_frame);
// test::small_matrix();
}
Ok(())
};
for (stream, packet) in ictx.packets() {
// else what?
// Is this for multiple video streams?
if stream.index() == video_stream_index {
decoder.send_packet(&packet)?;
receive_and_process_decoded_frames(&mut decoder)?;
}
}
decoder.send_eof()?;
receive_and_process_decoded_frames(&mut decoder)?;
}
Ok(())
}

62
src/test.rs Normal file
View File

@@ -0,0 +1,62 @@
use std::io::*;
use ffmpeg::format::Pixel;
use rand::Rng;
pub fn small_matrix() {
let mut matrix = [0u8; 432]; // 144 * 3 = 432
let mut rng = rand::thread_rng();
let r = rng.gen_range(0..50);
let g = rng.gen_range(0..50);
let b = rng.gen_range(0..50);
matrix.iter_mut().enumerate().for_each(|f| {
let value = match f.0 % 3 {
0 => r,
1 => g,
_ => b,
};
*f.1 = value;
});
print_raw(&matrix);
}
#[inline]
/// Asuumes a square ig
pub fn print_raw(buf: &[u8]) {
let mut stdout = stdout();
let mut lock = stdout.lock();
lock.write(buf).unwrap();
stdout.flush().unwrap();
}
/// Must use square images
// pub fn print_square(buf: &[u8], width_hight: usize, line) {
pub fn print_square(frame: &ffmpeg::frame::Video) {
if frame.format() != Pixel::RGB24 { panic!("Must use Pixel::RGB24"); }
if frame.width() != frame.height() { panic!("Must be square frames"); }
let buf = frame.data(0);
let size = frame.width() as usize;
// How many bytes per pixel RGBA
// frame.as_ptr();
let step = size*4;
// (Assuming square) Step thru buffer.
for i in 0..size*2 {
let j = i*step;
// Slices non-inclusively, ie: Even though j(n)+step = j(n+1) the ranges don't overlap. It take from..until
let pre_slice = &buf[j..j+step];
// Remove the last 12 bytes, alpha?
let slice = &pre_slice[0..size*3];
// let lol = &buf[j..j+step][0..size*3];
// Skip odd lines (they are filled with zeros)
if i & 1 != 1 {
// debug
println!("{:?} || {}-{}", slice, j, j+step);
}
}
}