Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix deep probe last frame #45

Merged
merged 5 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/probe/black_and_silence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub fn detect_black_and_silence(
video_indexes: Vec<u32>,
audio_indexes: Vec<u32>,
params: HashMap<String, CheckParameterValue>,
frame_duration: f32,
) {
let mut bas = BlackAndSilenceResult { start: 0, end: 0 };
let mut duration_min = None;
Expand Down Expand Up @@ -33,7 +34,7 @@ pub fn detect_black_and_silence(
bas.start = bl_detect.start;
}
if bas.start < bas.end {
let bas_duration: i64 = bas.end - bas.start;
let bas_duration: i64 = bas.end - bas.start + (frame_duration * 1000.0).round() as i64;
let detected_black_and_silence = streams[si_index as usize]
.detected_black_and_silence
.as_mut()
Expand Down
39 changes: 13 additions & 26 deletions src/probe/black_detect.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
use crate::{
format_context::FormatContext,
order::{
filter_input::FilterInput, filter_output::FilterOutput, input::Input, input_kind::InputKind,
output::Output, output_kind::OutputKind, stream::Stream, Filter, Order, OutputResult::Entry,
ParameterValue,
},
probe::deep::{BlackResult, CheckParameterValue, StreamProbeResult},
stream::Stream as ContextStream,
probe::deep::{BlackResult, CheckParameterValue, StreamProbeResult, VideoDetails},
};
use ffmpeg_sys_next::AVMediaType;
use std::collections::HashMap;

pub fn create_graph(
Expand Down Expand Up @@ -82,6 +79,7 @@ pub fn detect_black_frames(
streams: &mut [StreamProbeResult],
video_indexes: Vec<u32>,
params: HashMap<String, CheckParameterValue>,
video_details: VideoDetails,
) {
let mut order = create_graph(filename, video_indexes.clone(), params.clone()).unwrap();
if let Err(msg) = order.setup() {
Expand All @@ -96,31 +94,17 @@ pub fn detect_black_frames(
Ok(results) => {
info!("END OF PROCESS");
info!("-> {:?} frames processed", results.len());
let mut duration = 0;
let end_from_duration = match video_details.stream_duration {
Some(duration) => ((duration - video_details.frame_duration) * 1000.0).round() as i64,
None => ((results.len() as f32 - 1.0) / video_details.frame_rate * 1000.0).round() as i64,
};
let mut max_duration = None;
let mut min_duration = None;
if let Some(duration) = params.get("duration") {
max_duration = duration.max;
min_duration = duration.min;
}
let mut context = FormatContext::new(filename).unwrap();
if let Err(msg) = context.open_input() {
context.close_input();
error!("{:?}", msg);
return;
}
for index in 0..context.get_nb_streams() {
if let Ok(stream) = ContextStream::new(context.get_stream(index as isize)) {
if let AVMediaType::AVMEDIA_TYPE_VIDEO = context.get_stream_type(index as isize) {
let frame_rate = stream.get_frame_rate().to_float();
if let Some(stream_duration) = stream.get_duration() {
duration = (stream_duration * 1000.0) as i64;
} else {
duration = (results.len() as f32 / frame_rate * 1000.0) as i64;
}
}
}
}

for result in results {
if let Entry(entry_map) = result {
if let Some(stream_id) = entry_map.get("stream_id") {
Expand All @@ -132,7 +116,7 @@ pub fn detect_black_frames(
let detected_black = streams[(index) as usize].detected_black.as_mut().unwrap();
let mut black = BlackResult {
start: 0,
end: duration,
end: end_from_duration,
};

if let Some(value) = entry_map.get("lavfi.black_start") {
Expand All @@ -141,8 +125,11 @@ pub fn detect_black_frames(
}
if let Some(value) = entry_map.get("lavfi.black_end") {
if let Some(last_detect) = detected_black.last_mut() {
last_detect.end = (value.parse::<f32>().unwrap() * 1000.0).round() as i64;
let black_duration = last_detect.end - last_detect.start;
last_detect.end = ((value.parse::<f32>().unwrap() - video_details.frame_duration)
* 1000.0)
.round() as i64;
let black_duration = last_detect.end - last_detect.start
+ (video_details.frame_duration * 1000.0).round() as i64;
if let Some(max) = max_duration {
if black_duration > max as i64 {
detected_black.pop();
Expand Down
73 changes: 19 additions & 54 deletions src/probe/crop_detect.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
use crate::format_context::FormatContext;
use crate::order::{
filter_input::FilterInput, filter_output::FilterOutput, input::Input, input_kind::InputKind,
output::Output, output_kind::OutputKind, stream::Stream,
};
use crate::order::{Filter, Order, OutputResult::Entry, ParameterValue};
use crate::probe::deep::{CheckParameterValue, CropResult, StreamProbeResult};
use crate::stream::Stream as ContextStream;
use crate::tools::rational::Rational;
use ffmpeg_sys_next::AVMediaType;
use crate::probe::deep::{CheckParameterValue, CropResult, StreamProbeResult, VideoDetails};
use std::collections::HashMap;

pub fn create_graph(
Expand Down Expand Up @@ -91,31 +87,15 @@ pub fn detect_black_borders(
streams: &mut [StreamProbeResult],
video_indexes: Vec<u32>,
params: HashMap<String, CheckParameterValue>,
video_details: VideoDetails,
) {
let mut context = FormatContext::new(filename).unwrap();
if let Err(msg) = context.open_input() {
context.close_input();
error!("{:?}", msg);
return;
}

let mut nb_frames = 0;
let mut limit = 0;
for index in 0..context.get_nb_streams() {
if let Ok(stream) = ContextStream::new(context.get_stream(index as isize)) {
if let AVMediaType::AVMEDIA_TYPE_VIDEO = context.get_stream_type(index as isize) {
if let Some(frames) = stream.get_nb_frames() {
nb_frames = frames;
}
// black threshold : 16 pour 8bits / 64 pour 10bits / 256 pour 12bits
limit = match stream.get_bits_per_raw_sample() {
Some(10) => 64,
Some(12) => 256,
_ => 16,
}
}
}
}
let nb_frames = video_details.stream_frames.unwrap_or(0);
// black threshold : 16 pour 8bits / 64 pour 10bits / 256 pour 12bits
let limit = match video_details.bits_raw_sample {
Some(10) => 64,
Some(12) => 256,
_ => 16,
};
let mut order = create_graph(filename, video_indexes.clone(), params, nb_frames, limit).unwrap();
if let Err(msg) = order.setup() {
error!("{:?}", msg);
Expand All @@ -129,27 +109,11 @@ pub fn detect_black_borders(
Ok(results) => {
info!("END OF PROCESS");
info!("-> {:?} frames processed", results.len());
let mut time_base = 1.0;
let mut metadata_width = 0;
let mut metadata_height = 0;
let mut real_width = 0;
let mut real_height = 0;
let mut w_changed = false;
let mut h_changed = false;
let mut pict_size = Rational::new(1, 1);
let mut real_width = video_details.metadata_width;
let mut real_height = video_details.metadata_height;

for index in 0..context.get_nb_streams() {
if let Ok(stream) = ContextStream::new(context.get_stream(index as isize)) {
if let AVMediaType::AVMEDIA_TYPE_VIDEO = context.get_stream_type(index as isize) {
time_base = stream.get_time_base().to_float();
metadata_width = stream.get_width();
metadata_height = stream.get_height();
pict_size = stream.get_picture_aspect_ratio();
real_width = metadata_width;
real_height = metadata_height;
}
}
}
for result in results {
if let Entry(entry_map) = result {
if let Some(stream_id) = entry_map.get("stream_id") {
Expand All @@ -160,16 +124,16 @@ pub fn detect_black_borders(
}
let detected_crop = streams[(index) as usize].detected_crop.as_mut().unwrap();
let mut crop = CropResult {
width: metadata_width,
height: metadata_height,
width: video_details.metadata_width,
height: video_details.metadata_height,
..Default::default()
};
if let (Some(x1), Some(x2)) = (
entry_map.get("lavfi.cropdetect.x1"),
entry_map.get("lavfi.cropdetect.x2"),
) {
let width = x2.parse::<i32>().unwrap() - x1.parse::<i32>().unwrap() + 1;
if width != metadata_width {
if width != video_details.metadata_width {
w_changed = true;
}
real_width = width;
Expand All @@ -179,7 +143,7 @@ pub fn detect_black_borders(
entry_map.get("lavfi.cropdetect.y2"),
) {
let height = y2.parse::<i32>().unwrap() - y1.parse::<i32>().unwrap() + 1;
if height != metadata_height {
if height != video_details.metadata_height {
h_changed = true;
}
real_height = height;
Expand All @@ -188,9 +152,10 @@ pub fn detect_black_borders(
if w_changed || h_changed {
crop.width = real_width;
crop.height = real_height;
crop.pts = (pts.parse::<f32>().unwrap() * time_base * 1000.0).round() as i64;
let real_aspect =
(real_width * pict_size.num) as f32 / (real_height * pict_size.den) as f32;
crop.pts =
(pts.parse::<f32>().unwrap() * video_details.time_base * 1000.0).round() as i64;
let real_aspect = (real_width * video_details.aspect_ratio.num) as f32
/ (real_height * video_details.aspect_ratio.den) as f32;
crop.aspect_ratio = real_aspect;
detected_crop.push(crop);
w_changed = false;
Expand Down
55 changes: 54 additions & 1 deletion src/probe/deep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::probe::scene_detect::detect_scene;
use crate::probe::silence_detect::detect_silence;
use crate::probe::sine_detect::detect_sine;
use crate::stream::Stream;
use crate::tools::rational::Rational;
use ffmpeg_sys_next::*;
use log::LevelFilter;
use std::{cmp, collections::HashMap, fmt};
Expand Down Expand Up @@ -173,6 +174,19 @@ pub struct DeepProbeCheck {
pub sine_detect: Option<HashMap<String, CheckParameterValue>>,
}

#[derive(Clone, Debug, Default)]
pub struct VideoDetails {
pub frame_rate: f32,
pub time_base: f32,
pub frame_duration: f32,
pub stream_duration: Option<f32>,
pub stream_frames: Option<i64>,
pub bits_raw_sample: Option<i32>,
pub metadata_width: i32,
pub metadata_height: i32,
pub aspect_ratio: Rational,
}

impl fmt::Display for DeepProbeResult {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (index, stream) in self.streams.iter().enumerate() {
Expand Down Expand Up @@ -300,6 +314,22 @@ impl Track {
}
}

impl VideoDetails {
pub fn new() -> Self {
VideoDetails {
frame_rate: 1.0,
time_base: 1.0,
frame_duration: 0.0,
stream_duration: None,
stream_frames: None,
bits_raw_sample: None,
metadata_width: 0,
metadata_height: 0,
aspect_ratio: Rational::new(1, 1),
}
}
}

impl DeepProbe {
pub fn new(filename: &str, id: Uuid) -> Self {
DeepProbe {
Expand Down Expand Up @@ -330,6 +360,7 @@ impl DeepProbe {
return Ok(());
}

let mut video_details = VideoDetails::new();
let mut streams = vec![];
streams.resize(context.get_nb_streams() as usize, StreamProbeResult::new());
while let Ok(packet) = context.next_packet() {
Expand All @@ -351,6 +382,15 @@ impl DeepProbe {
streams[stream_index].color_primaries = stream.get_color_primaries();
streams[stream_index].color_trc = stream.get_color_trc();
streams[stream_index].color_matrix = stream.get_color_matrix();
video_details.frame_duration = stream.get_frame_rate().invert().to_float();
video_details.frame_rate = stream.get_frame_rate().to_float();
video_details.time_base = stream.get_time_base().to_float();
video_details.stream_duration = stream.get_duration();
video_details.stream_frames = stream.get_nb_frames();
video_details.bits_raw_sample = stream.get_bits_per_raw_sample();
video_details.metadata_width = stream.get_width();
video_details.metadata_height = stream.get_height();
video_details.aspect_ratio = stream.get_picture_aspect_ratio();
}
}
}
Expand All @@ -373,6 +413,7 @@ impl DeepProbe {
&mut streams,
audio_indexes.clone(),
silence_parameters,
video_details.clone(),
);
}

Expand All @@ -382,6 +423,7 @@ impl DeepProbe {
&mut streams,
video_indexes.clone(),
black_parameters,
video_details.clone(),
);
}

Expand All @@ -392,6 +434,7 @@ impl DeepProbe {
video_indexes.clone(),
audio_indexes.clone(),
black_and_silence_parameters,
video_details.frame_duration,
);
}
}
Expand All @@ -402,6 +445,7 @@ impl DeepProbe {
&mut streams,
video_indexes.clone(),
crop_parameters,
video_details.clone(),
);
}

Expand All @@ -411,6 +455,7 @@ impl DeepProbe {
&mut streams,
video_indexes.clone(),
scene_parameters,
video_details.frame_rate,
);
}

Expand All @@ -420,6 +465,7 @@ impl DeepProbe {
&mut streams,
video_indexes.clone(),
ocr_parameters,
video_details.clone(),
);
}

Expand All @@ -444,11 +490,18 @@ impl DeepProbe {
&mut streams,
audio_indexes.clone(),
dualmono_parameters,
video_details.clone(),
);
}

if let Some(sine_parameters) = check.sine_detect {
detect_sine(&self.filename, &mut streams, audio_indexes, sine_parameters);
detect_sine(
&self.filename,
&mut streams,
audio_indexes,
sine_parameters,
video_details.frame_rate,
);
}

let mut format = FormatProbeResult::new();
Expand Down
Loading
Loading