From eaeec0a0fbb1ee2d63ec7ad68419589348593de7 Mon Sep 17 00:00:00 2001 From: Romane Lafon Date: Mon, 20 Nov 2023 18:38:26 +0100 Subject: [PATCH] remove getting stream data from detect functions --- src/probe/black_detect.rs | 33 +++++-------------- src/probe/crop_detect.rs | 62 ++++++++++-------------------------- src/probe/deep.rs | 41 +++++++++++++++++++++++- src/probe/dualmono_detect.rs | 31 ++++-------------- src/probe/loudness_detect.rs | 7 ---- src/probe/ocr_detect.rs | 27 +++------------- src/probe/scene_detect.rs | 19 ++--------- src/probe/silence_detect.rs | 32 +++++-------------- src/probe/sine_detect.rs | 30 +++++++---------- 9 files changed, 97 insertions(+), 185 deletions(-) diff --git a/src/probe/black_detect.rs b/src/probe/black_detect.rs index 3982068..afd1a12 100644 --- a/src/probe/black_detect.rs +++ b/src/probe/black_detect.rs @@ -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, }; -use ffmpeg_sys_next::AVMediaType; use std::collections::HashMap; pub fn create_graph( @@ -82,6 +79,9 @@ pub fn detect_black_frames( streams: &mut [StreamProbeResult], video_indexes: Vec, params: HashMap, + frame_rate: f32, + frame_duration: f32, + stream_duration: Option, ) { let mut order = create_graph(filename, video_indexes.clone(), params.clone()).unwrap(); if let Err(msg) = order.setup() { @@ -96,34 +96,17 @@ pub fn detect_black_frames( Ok(results) => { info!("END OF PROCESS"); info!("-> {:?} frames processed", results.len()); - let mut end_from_duration = 0; + let end_from_duration = match stream_duration { + Some(duration) => ((duration - frame_duration) * 1000.0).round() as i64, + None => ((results.len() as f32 - 1.0) / frame_rate * 1000.0).round() as i64, + }; let mut max_duration = None; let mut min_duration = None; - let mut frame_duration = 0.0; 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(); - frame_duration = stream.get_frame_rate().invert().to_float(); - if let Some(stream_duration) = stream.get_duration() { - end_from_duration = ((stream_duration - frame_duration) * 1000.0).round() as i64; - } else { - end_from_duration = - ((results.len() as f32 - 1.0) / frame_rate * 1000.0).round() as i64; - } - } - } - } + for result in results { if let Entry(entry_map) = result { if let Some(stream_id) = entry_map.get("stream_id") { diff --git a/src/probe/crop_detect.rs b/src/probe/crop_detect.rs index c997d79..dfb2625 100644 --- a/src/probe/crop_detect.rs +++ b/src/probe/crop_detect.rs @@ -1,13 +1,10 @@ -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 std::collections::HashMap; pub fn create_graph( @@ -91,31 +88,20 @@ pub fn detect_black_borders( streams: &mut [StreamProbeResult], video_indexes: Vec, params: HashMap, + stream_frames: Option, + bits_raw_sample: Option, + time_base: f32, + metadata_width: i32, + metadata_height: i32, + aspect_ratio: Rational, ) { - 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 = stream_frames.unwrap_or(0); + // black threshold : 16 pour 8bits / 64 pour 10bits / 256 pour 12bits + let limit = match 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); @@ -129,27 +115,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 = metadata_width; + let mut real_height = 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") { @@ -190,7 +160,7 @@ pub fn detect_black_borders( crop.height = real_height; crop.pts = (pts.parse::().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; + (real_width * aspect_ratio.num) as f32 / (real_height * aspect_ratio.den) as f32; crop.aspect_ratio = real_aspect; detected_crop.push(crop); w_changed = false; diff --git a/src/probe/deep.rs b/src/probe/deep.rs index 266dda1..e26b693 100644 --- a/src/probe/deep.rs +++ b/src/probe/deep.rs @@ -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}; @@ -331,6 +332,14 @@ impl DeepProbe { } let mut frame_duration = 0.0; + let mut frame_rate = 1.0; + let mut time_base = 1.0; + let mut metadata_width = 0; + let mut metadata_height = 0; + let mut stream_duration = None; + let mut stream_frames = None; + let mut bits_raw_sample = None; + let mut aspect_ratio = Rational::new(1, 1); let mut streams = vec![]; streams.resize(context.get_nb_streams() as usize, StreamProbeResult::new()); while let Ok(packet) = context.next_packet() { @@ -353,6 +362,14 @@ impl DeepProbe { streams[stream_index].color_trc = stream.get_color_trc(); streams[stream_index].color_matrix = stream.get_color_matrix(); frame_duration = stream.get_frame_rate().invert().to_float(); + frame_rate = stream.get_frame_rate().to_float(); + time_base = stream.get_time_base().to_float(); + stream_duration = stream.get_duration(); + stream_frames = stream.get_nb_frames(); + bits_raw_sample = stream.get_bits_per_raw_sample(); + metadata_width = stream.get_width(); + metadata_height = stream.get_height(); + aspect_ratio = stream.get_picture_aspect_ratio(); } } } @@ -375,6 +392,8 @@ impl DeepProbe { &mut streams, audio_indexes.clone(), silence_parameters, + frame_rate, + frame_duration, ); } @@ -384,6 +403,9 @@ impl DeepProbe { &mut streams, video_indexes.clone(), black_parameters, + frame_rate, + frame_duration, + stream_duration, ); } @@ -405,6 +427,12 @@ impl DeepProbe { &mut streams, video_indexes.clone(), crop_parameters, + stream_frames, + bits_raw_sample, + time_base, + metadata_width, + metadata_height, + aspect_ratio, ); } @@ -414,6 +442,7 @@ impl DeepProbe { &mut streams, video_indexes.clone(), scene_parameters, + frame_rate, ); } @@ -423,6 +452,8 @@ impl DeepProbe { &mut streams, video_indexes.clone(), ocr_parameters, + frame_rate, + stream_frames, ); } @@ -447,11 +478,19 @@ impl DeepProbe { &mut streams, audio_indexes.clone(), dualmono_parameters, + frame_rate, + frame_duration, ); } 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, + frame_rate, + ); } let mut format = FormatProbeResult::new(); diff --git a/src/probe/dualmono_detect.rs b/src/probe/dualmono_detect.rs index dac89b7..7fabaf8 100644 --- a/src/probe/dualmono_detect.rs +++ b/src/probe/dualmono_detect.rs @@ -1,4 +1,3 @@ -use crate::format_context::FormatContext; use crate::{ order::{ filter_input::FilterInput, filter_output::FilterOutput, input::Input, input_kind::InputKind, @@ -6,9 +5,7 @@ use crate::{ ParameterValue, }, probe::deep::{CheckParameterValue, DualMonoResult, StreamProbeResult}, - stream::Stream as ContextStream, }; -use ffmpeg_sys_next::AVMediaType; use std::collections::HashMap; pub fn create_graph( @@ -119,10 +116,11 @@ pub fn detect_dualmono( streams: &mut [StreamProbeResult], audio_indexes: Vec, params: HashMap, + frame_rate: f32, + frame_duration: f32, ) { let mut order = create_graph(filename, ¶ms).unwrap(); let mut max_duration = None; - let mut frame_duration = 0.0; if let Some(duration) = params.get("duration") { max_duration = duration.max; } @@ -138,7 +136,6 @@ pub fn detect_dualmono( Ok(results) => { info!("END OF PROCESS"); info!("-> {:?} frames processed", results.len()); - let mut end_from_duration = 0; let mut audio_stream_qualif_number = 0; match params.get("pairing_list") { @@ -157,24 +154,10 @@ pub fn detect_dualmono( None => warn!("No input message for the dualmono analysis (list of indexes to merge)"), } - 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() as f64; - frame_duration = stream.get_frame_rate().invert().to_float() as f64; - end_from_duration = (((results.len() as f64 / audio_stream_qualif_number as f64) - 1.0) - / frame_rate - * 1000.0) - .round() as i64; - } - } - } + let end_from_duration = (((results.len() as f64 / audio_stream_qualif_number as f64) - 1.0) + / frame_rate as f64 + * 1000.0) + .round() as i64; for result in results { if let Entry(entry_map) = result { if let Some(stream_id) = entry_map.get("stream_id") { @@ -198,7 +181,7 @@ pub fn detect_dualmono( if let Some(value) = entry_map.get("lavfi.aphasemeter.mono_end") { if let Some(last_detect) = detected_dualmono.last_mut() { last_detect.end = - ((value.parse::().unwrap() - frame_duration) * 1000.0).round() as i64; + ((value.parse::().unwrap() - frame_duration as f64) * 1000.0).round() as i64; } } if let Some(value) = entry_map.get("lavfi.aphasemeter.mono_duration") { diff --git a/src/probe/loudness_detect.rs b/src/probe/loudness_detect.rs index 9f4e0db..460607e 100644 --- a/src/probe/loudness_detect.rs +++ b/src/probe/loudness_detect.rs @@ -1,4 +1,3 @@ -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, Filter, Order, OutputResult::Entry, @@ -126,12 +125,6 @@ pub fn detect_loudness( Ok(results) => { info!("END OF PROCESS"); info!("-> {:?} frames processed", results.len()); - let mut context = FormatContext::new(filename).unwrap(); - if let Err(msg) = context.open_input() { - context.close_input(); - error!("{:?}", msg); - return; - } for result in results { if let Entry(entry_map) = result { if let Some(stream_id) = entry_map.get("stream_id") { diff --git a/src/probe/ocr_detect.rs b/src/probe/ocr_detect.rs index 4f19f2b..8672f1d 100644 --- a/src/probe/ocr_detect.rs +++ b/src/probe/ocr_detect.rs @@ -1,12 +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, Filter, Order, OutputResult::Entry, ParameterValue, }; use crate::probe::deep::{CheckParameterValue, OcrResult, StreamProbeResult}; -use crate::stream::Stream as ContextStream; -use ffmpeg_sys_next::AVMediaType; use std::collections::HashMap; pub fn create_graph( @@ -80,6 +77,8 @@ pub fn detect_ocr( streams: &mut [StreamProbeResult], video_indexes: Vec, params: HashMap, + frame_rate: f32, + stream_frames: Option, ) { let mut order = create_graph(filename, video_indexes.clone(), ¶ms).unwrap(); if let Err(msg) = order.setup() { @@ -94,27 +93,9 @@ pub fn detect_ocr( Ok(results) => { info!("END OF PROCESS"); info!("-> {:?} frames processed", results.len()); - let mut frame_rate = 1.0; let mut media_offline_detected = false; - let mut last_frame = 0; - 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) { - frame_rate = stream.get_frame_rate().to_float(); - if let Some(nb_frames) = stream.get_nb_frames() { - last_frame = nb_frames - 1; - } else { - last_frame = results.len() as i64 - 1; - } - } - } - } + let last_frame = stream_frames.unwrap_or(results.len() as i64) - 1; + for result in results { if let Entry(entry_map) = result { if let Some(stream_id) = entry_map.get("stream_id") { diff --git a/src/probe/scene_detect.rs b/src/probe/scene_detect.rs index 10ad29f..f5701cd 100644 --- a/src/probe/scene_detect.rs +++ b/src/probe/scene_detect.rs @@ -1,12 +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, Filter, Order, OutputResult::Entry, ParameterValue, }; use crate::probe::deep::{CheckParameterValue, FalseSceneResult, SceneResult, StreamProbeResult}; -use crate::stream::Stream as ContextStream; -use ffmpeg_sys_next::AVMediaType; use std::collections::HashMap; pub fn create_graph( @@ -67,6 +64,7 @@ pub fn detect_scene( streams: &mut [StreamProbeResult], video_indexes: Vec, params: HashMap, + frame_rate: f32, ) { let mut order = create_graph(filename, video_indexes.clone(), ¶ms).unwrap(); if let Err(msg) = order.setup() { @@ -82,21 +80,8 @@ pub fn detect_scene( Ok(results) => { info!("END OF PROCESS"); info!("-> {:?} frames processed", results.len()); - let mut frame_rate = 1.0; let mut scene_count = 0; - 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) { - frame_rate = stream.get_frame_rate().to_float(); - } - } - } + for result in results { if let Entry(entry_map) = result { if let Some(stream_id) = entry_map.get("stream_id") { diff --git a/src/probe/silence_detect.rs b/src/probe/silence_detect.rs index e76484e..eb6ef9e 100644 --- a/src/probe/silence_detect.rs +++ b/src/probe/silence_detect.rs @@ -1,12 +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, Filter, Order, OutputResult::Entry, ParameterValue, }; use crate::probe::deep::{CheckParameterValue, SilenceResult, StreamProbeResult}; -use crate::stream::Stream as ContextStream; -use ffmpeg_sys_next::AVMediaType; use std::collections::HashMap; pub fn create_graph( @@ -86,6 +83,8 @@ pub fn detect_silence( streams: &mut [StreamProbeResult], audio_indexes: Vec, params: HashMap, + frame_rate: f32, + frame_duration: f32, ) { let mut order = create_graph(filename, audio_indexes.clone(), ¶ms).unwrap(); if let Err(msg) = order.setup() { @@ -100,26 +99,11 @@ pub fn detect_silence( Ok(results) => { info!("END OF PROCESS"); info!("-> {:?} frames processed", results.len()); - let mut end_from_duration = 0; - let mut frame_duration = 0.0; - 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() as f64; - frame_duration = stream.get_frame_rate().invert().to_float() as f64; - end_from_duration = - (((results.len() as f64 / audio_indexes.clone().len() as f64) - 1.0) / frame_rate - * 1000.0) - .round() as i64; - } - } - } + let end_from_duration = (((results.len() as f64 / audio_indexes.clone().len() as f64) - 1.0) + / frame_rate as f64 + * 1000.0) + .round() as i64; + let mut max_duration = None; if let Some(duration) = params.get("duration") { max_duration = duration.max; @@ -145,7 +129,7 @@ pub fn detect_silence( if let Some(value) = entry_map.get("lavfi.silence_end") { if let Some(last_detect) = detected_silence.last_mut() { last_detect.end = - ((value.parse::().unwrap() - frame_duration) * 1000.0).round() as i64; + ((value.parse::().unwrap() - frame_duration as f64) * 1000.0).round() as i64; } } if let Some(value) = entry_map.get("lavfi.silence_duration") { diff --git a/src/probe/sine_detect.rs b/src/probe/sine_detect.rs index 8f50f84..09d4355 100644 --- a/src/probe/sine_detect.rs +++ b/src/probe/sine_detect.rs @@ -95,6 +95,7 @@ pub fn detect_sine( streams: &mut [StreamProbeResult], audio_indexes: Vec, params: HashMap, + frame_rate: f32, ) { let mut order = create_graph(filename, audio_indexes.clone(), ¶ms).unwrap(); if let Err(msg) = order.setup() { @@ -109,8 +110,9 @@ pub fn detect_sine( Ok(results) => { info!("END OF PROCESS"); info!("-> {:?} frames processed", results.len()); - let mut end_from_duration = 0; - let mut frame_rate = 1.0; + let end_from_duration = + (((results.len() as f64 / audio_indexes.len() as f64) - 1.0) / frame_rate as f64 * 1000.0) + .round() as i64; let mut tracks: Vec> = Vec::new(); let mut sine: SineResult = Default::default(); let mut range_value: f64 = 1.0; //contains the range values to code a sample @@ -139,16 +141,6 @@ pub fn detect_sine( 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) { - frame_rate = stream.get_frame_rate().to_float() as f64; - end_from_duration = - (((results.len() as f64 / audio_indexes.len() as f64) - 1.0) / frame_rate * 1000.0) - .round() as i64; - } - } - } for result in results { if let Entry(entry_map) = result { if let Some(stream_id) = entry_map.get("stream_id") { @@ -212,14 +204,15 @@ pub fn detect_sine( if last_start_opt.is_some() { if let Some(last_start) = last_start_opt { //check if audio ends => 1000Hz until the end - if (frame / frame_rate * 1000.0).round() as i64 == end_from_duration { + if (frame / frame_rate as f64 * 1000.0).round() as i64 == end_from_duration { sine.channel = channel; sine.start = *last_start; sine.end = end_from_duration; //check if sine is a 1000Hz => push and reset if let Some(zero_crossing) = zero_cross.get(&audio_stream_key.clone()) { - let sine_duration = - ((frame + 1.0) / frame_rate * 1000.0).round() as i64 - sine.start; + let sine_duration = ((frame + 1.0) / frame_rate as f64 * 1000.0).round() + as i64 + - sine.start; if (zero_crossing / sine_duration as f64) == 2.0 { detected_sine.push(sine); last_starts.insert(audio_stream_key.clone(), None); @@ -239,7 +232,7 @@ pub fn detect_sine( } } } else { - sine.start = (frame / frame_rate * 1000.0).round() as i64; + sine.start = (frame / frame_rate as f64 * 1000.0).round() as i64; last_starts.insert(audio_stream_key.clone(), Some(sine.start)); } } else if (2_f64.sqrt() - 1e-3_f64..2_f64.sqrt() + 1e-3_f64) @@ -249,9 +242,10 @@ pub fn detect_sine( if let Some(last_start) = last_start_opt { sine.channel = channel; sine.start = *last_start; - sine.end = ((frame - 1.0) / frame_rate * 1000.0).round() as i64; + sine.end = ((frame - 1.0) / frame_rate as f64 * 1000.0).round() as i64; //check if sine is a 1000Hz => push and reset - let sine_duration = (frame / frame_rate * 1000.0).round() as i64 - sine.start; + let sine_duration = + (frame / frame_rate as f64 * 1000.0).round() as i64 - sine.start; if let Some(zero_crossing) = zero_cross.get(&audio_stream_key) { if (zero_crossing / sine_duration as f64) == 2.0 { detected_sine.push(sine);