use std::time::Duration;
use ffmpeg_next::{Rational, frame::Video as VideoFrame};
pub fn frame_to_buffer(
video_frame: &VideoFrame,
width: u32,
height: u32,
bytes_per_pixel: usize,
) -> Vec<u8> {
let stride = video_frame.stride(0);
let expected_stride = (width as usize) * bytes_per_pixel;
let data = video_frame.data(0);
if stride == expected_stride {
data[..expected_stride * (height as usize)].to_vec()
} else {
let mut buffer = Vec::with_capacity(expected_stride * (height as usize));
for row in 0..(height as usize) {
let row_start = row * stride;
buffer.extend_from_slice(&data[row_start..row_start + expected_stride]);
}
buffer
}
}
pub fn duration_to_stream_timestamp(duration: Duration, time_base: Rational) -> i64 {
let seconds = duration.as_secs_f64();
let numerator = time_base.numerator() as f64;
let denominator = time_base.denominator() as f64;
(seconds * denominator / numerator) as i64
}
pub fn timestamp_to_frame_number(timestamp: Duration, frames_per_second: f64) -> u64 {
(timestamp.as_secs_f64() * frames_per_second) as u64
}
pub fn pts_to_seconds(pts: i64, time_base: Rational) -> f64 {
pts as f64 * time_base.numerator() as f64 / time_base.denominator() as f64
}
pub fn pts_to_frame_number(pts: i64, time_base: Rational, frames_per_second: f64) -> u64 {
let seconds = pts_to_seconds(pts, time_base);
(seconds * frames_per_second) as u64
}
pub fn frame_number_to_seek_timestamp(frame_number: u64, frames_per_second: f64) -> i64 {
let seconds = frame_number as f64 / frames_per_second;
(seconds * 1_000_000.0) as i64
}
pub fn duration_to_seek_timestamp(duration: Duration) -> i64 {
duration.as_micros() as i64
}