-
Notifications
You must be signed in to change notification settings - Fork 210
/
dump-frames.rs
66 lines (56 loc) · 2.17 KB
/
dump-frames.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
extern crate ffmpeg_next as ffmpeg;
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::env;
use std::fs::File;
use std::io::prelude::*;
fn main() -> Result<(), ffmpeg::Error> {
ffmpeg::init().unwrap();
if let Ok(mut ictx) = input(&env::args().nth(1).expect("Cannot open file.")) {
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())?;
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,
)?;
let mut frame_index = 0;
let mut receive_and_process_decoded_frames =
|decoder: &mut ffmpeg::decoder::Video| -> Result<(), ffmpeg::Error> {
let mut decoded = Video::empty();
while decoder.receive_frame(&mut decoded).is_ok() {
let mut rgb_frame = Video::empty();
scaler.run(&decoded, &mut rgb_frame)?;
save_file(&rgb_frame, frame_index).unwrap();
frame_index += 1;
}
Ok(())
};
for (stream, packet) in ictx.packets() {
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(())
}
fn save_file(frame: &Video, index: usize) -> std::result::Result<(), std::io::Error> {
let mut file = File::create(format!("frame{}.ppm", index))?;
file.write_all(format!("P6\n{} {}\n255\n", frame.width(), frame.height()).as_bytes())?;
file.write_all(frame.data(0))?;
Ok(())
}