dump_frames/
dump-frames.rs1extern crate ffmpeg_next as ffmpeg;
2
3use crate::ffmpeg::format::{Pixel, input};
4use crate::ffmpeg::media::Type;
5use crate::ffmpeg::software::scaling::{context::Context, flag::Flags};
6use crate::ffmpeg::util::frame::video::Video;
7use std::env;
8use std::fs::File;
9use std::io::prelude::*;
10
11fn main() -> Result<(), ffmpeg::Error> {
12 ffmpeg::init().unwrap();
13
14 if let Ok(mut ictx) = input(&env::args().nth(1).expect("Cannot open file.")) {
15 let input = ictx
16 .streams()
17 .best(Type::Video)
18 .ok_or(ffmpeg::Error::StreamNotFound)?;
19 let video_stream_index = input.index();
20
21 let context_decoder = ffmpeg::codec::context::Context::from_parameters(input.parameters())?;
22 let mut decoder = context_decoder.decoder().video()?;
23
24 let mut scaler = Context::get(
25 decoder.format(),
26 decoder.width(),
27 decoder.height(),
28 Pixel::RGB24,
29 decoder.width(),
30 decoder.height(),
31 Flags::BILINEAR,
32 )?;
33
34 let mut frame_index = 0;
35
36 let mut receive_and_process_decoded_frames =
37 |decoder: &mut ffmpeg::decoder::Video| -> Result<(), ffmpeg::Error> {
38 let mut decoded = Video::empty();
39 while decoder.receive_frame(&mut decoded).is_ok() {
40 let mut rgb_frame = Video::empty();
41 scaler.run(&decoded, &mut rgb_frame)?;
42 save_file(&rgb_frame, frame_index).unwrap();
43 frame_index += 1;
44 }
45 Ok(())
46 };
47
48 for (stream, packet) in ictx.packets() {
49 if stream.index() == video_stream_index {
50 decoder.send_packet(&packet)?;
51 receive_and_process_decoded_frames(&mut decoder)?;
52 }
53 }
54 decoder.send_eof()?;
55 receive_and_process_decoded_frames(&mut decoder)?;
56 }
57
58 Ok(())
59}
60
61fn save_file(frame: &Video, index: usize) -> std::result::Result<(), std::io::Error> {
62 let mut file = File::create(format!("frame{}.ppm", index))?;
63 file.write_all(format!("P6\n{} {}\n255\n", frame.width(), frame.height()).as_bytes())?;
64 for i in 0..frame.height() as usize {
65 let start = i * frame.stride(0);
66 let len = 3 * frame.width() as usize;
67 file.write_all(&frame.data(0)[start..start + len])?;
68 }
69 Ok(())
70}