Skip to content

Commit

Permalink
Merge pull request #56 from nomalab/fix_audio_results
Browse files Browse the repository at this point in the history
fix audio results
  • Loading branch information
Romanelaf authored Oct 24, 2024
2 parents b8451be + 1c21af1 commit 17fc78a
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 69 deletions.
82 changes: 53 additions & 29 deletions src/probe/deep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ pub struct SineResult {
pub struct StreamProbeResult {
stream_index: usize,
count_packets: usize,
total_packets_duration: i64,
min_packet_size: i32,
max_packet_size: i32,
pub color_space: Option<String>,
Expand Down Expand Up @@ -202,7 +203,14 @@ pub struct VideoDetails {
pub metadata_width: i32,
pub metadata_height: i32,
pub aspect_ratio: Rational,
}

#[derive(Clone, Debug, Default)]
pub struct AudioDetails {
pub stream_index: i32,
pub stream_duration: Option<f32>,
pub sample_rate: i32,
pub samples_per_frame: i32,
}

#[derive(Default)]
Expand All @@ -212,6 +220,7 @@ pub struct DeepOrder {
output_results: BTreeMap<CheckName, Vec<OutputResult>>,
streams: Vec<StreamProbeResult>,
video_details: VideoDetails,
audio_details: Vec<AudioDetails>,
audio_indexes: Vec<u32>,
video_indexes: Vec<u32>,
}
Expand All @@ -235,6 +244,11 @@ impl fmt::Display for DeepProbeResult {
for (index, stream) in self.streams.iter().enumerate() {
writeln!(f, "\n{:30} : {:?}", "Stream Index", index)?;
writeln!(f, "{:30} : {:?}", "Number of packets", stream.count_packets)?;
writeln!(
f,
"{:30} : {:?}",
"Total packets duration", stream.total_packets_duration
)?;
writeln!(
f,
"{:30} : {:?}",
Expand Down Expand Up @@ -307,6 +321,7 @@ impl StreamProbeResult {
StreamProbeResult {
stream_index: 0,
count_packets: 0,
total_packets_duration: 0,
color_space: None,
color_range: None,
color_primaries: None,
Expand Down Expand Up @@ -369,7 +384,6 @@ impl VideoDetails {
metadata_width: 0,
metadata_height: 0,
aspect_ratio: Rational::new(1, 1),
sample_rate: 0,
}
}
}
Expand All @@ -382,6 +396,7 @@ impl DeepOrder {
output_results: BTreeMap::new(),
streams: vec![],
video_details: VideoDetails::new(),
audio_details: vec![],
audio_indexes: vec![],
video_indexes: vec![],
}
Expand Down Expand Up @@ -410,9 +425,11 @@ impl DeepProbe {
unsafe {
let stream_index = (*packet.packet).stream_index as usize;
let packet_size = (*packet.packet).size;
let packet_duration = (*packet.packet).duration;

deep_orders.streams[stream_index].stream_index = stream_index;
deep_orders.streams[stream_index].count_packets += 1;
deep_orders.streams[stream_index].total_packets_duration += packet_duration;
deep_orders.streams[stream_index].min_packet_size = cmp::min(
packet_size,
deep_orders.streams[stream_index].min_packet_size,
Expand All @@ -421,30 +438,6 @@ impl DeepProbe {
packet_size,
deep_orders.streams[stream_index].max_packet_size,
);

if context.get_stream_type(stream_index as isize) == AVMediaType::AVMEDIA_TYPE_VIDEO {
if let Ok(stream) = Stream::new(context.get_stream(stream_index as isize)) {
deep_orders.streams[stream_index].color_space = stream.get_color_space();
deep_orders.streams[stream_index].color_range = stream.get_color_range();
deep_orders.streams[stream_index].color_primaries = stream.get_color_primaries();
deep_orders.streams[stream_index].color_trc = stream.get_color_trc();
deep_orders.streams[stream_index].color_matrix = stream.get_color_matrix();
deep_orders.video_details.frame_duration = stream.get_frame_rate().invert().to_float();
deep_orders.video_details.frame_rate = stream.get_frame_rate().to_float();
deep_orders.video_details.time_base = stream.get_time_base().to_float();
deep_orders.video_details.stream_duration = stream.get_duration();
deep_orders.video_details.stream_frames = stream.get_nb_frames();
deep_orders.video_details.bits_raw_sample = stream.get_bits_per_raw_sample();
deep_orders.video_details.metadata_width = stream.get_width();
deep_orders.video_details.metadata_height = stream.get_height();
deep_orders.video_details.aspect_ratio = stream.get_picture_aspect_ratio();
}
}
if context.get_stream_type(stream_index as isize) == AVMediaType::AVMEDIA_TYPE_AUDIO {
if let Ok(stream) = Stream::new(context.get_stream(stream_index as isize)) {
deep_orders.video_details.sample_rate = stream.get_sample_rate();
}
}
}
}

Expand All @@ -453,10 +446,39 @@ impl DeepProbe {
if context.get_stream_type(stream_index as isize) == AVMediaType::AVMEDIA_TYPE_VIDEO {
deep_orders.video_indexes.push(stream_index);
input_id = format!("video_input_{}", stream_index);
if let Ok(stream) = Stream::new(context.get_stream(stream_index as isize)) {
deep_orders.streams[stream_index as usize].color_space = stream.get_color_space();
deep_orders.streams[stream_index as usize].color_range = stream.get_color_range();
deep_orders.streams[stream_index as usize].color_primaries = stream.get_color_primaries();
deep_orders.streams[stream_index as usize].color_trc = stream.get_color_trc();
deep_orders.streams[stream_index as usize].color_matrix = stream.get_color_matrix();
deep_orders.video_details.frame_duration = stream.get_frame_rate().invert().to_float();
deep_orders.video_details.frame_rate = stream.get_frame_rate().to_float();
deep_orders.video_details.time_base = stream.get_time_base().to_float();
deep_orders.video_details.stream_duration = stream.get_duration();
deep_orders.video_details.stream_frames = stream.get_nb_frames();
deep_orders.video_details.bits_raw_sample = stream.get_bits_per_raw_sample();
deep_orders.video_details.metadata_width = stream.get_width();
deep_orders.video_details.metadata_height = stream.get_height();
deep_orders.video_details.aspect_ratio = stream.get_picture_aspect_ratio();
}
}
if context.get_stream_type(stream_index as isize) == AVMediaType::AVMEDIA_TYPE_AUDIO {
deep_orders.audio_indexes.push(stream_index);
input_id = format!("audio_input_{}", stream_index);
if let Ok(stream) = Stream::new(context.get_stream(stream_index as isize)) {
let avg_pkt_duration = (deep_orders.streams[stream_index as usize].total_packets_duration
as f64
/ deep_orders.streams[stream_index as usize].count_packets as f64)
.ceil();
let audio_stream_details: AudioDetails = AudioDetails {
stream_index: stream_index as i32,
stream_duration: stream.get_duration(),
sample_rate: stream.get_sample_rate(),
samples_per_frame: avg_pkt_duration as i32,
};
deep_orders.audio_details.push(audio_stream_details);
}
}
if context.get_stream_type(stream_index as isize) == AVMediaType::AVMEDIA_TYPE_SUBTITLE {
input_id = format!("subtitle_input_{}", stream_index);
Expand Down Expand Up @@ -581,7 +603,8 @@ impl DeepProbe {
&mut deep_orders.streams,
deep_orders.audio_indexes.clone(),
params,
deep_orders.video_details.clone(),
deep_orders.video_details.frame_duration,
deep_orders.audio_details.clone(),
);
}
}
Expand Down Expand Up @@ -639,7 +662,7 @@ impl DeepProbe {
&mut deep_orders.streams,
deep_orders.audio_indexes.clone(),
params,
deep_orders.video_details.clone(),
deep_orders.audio_details.clone(),
)
}
}
Expand All @@ -650,7 +673,8 @@ impl DeepProbe {
&mut deep_orders.streams,
deep_orders.audio_indexes.clone(),
params,
deep_orders.video_details.clone(),
deep_orders.video_details.frame_duration,
deep_orders.audio_details.clone(),
)
}
}
Expand All @@ -662,7 +686,7 @@ impl DeepProbe {
&mut deep_orders.streams,
deep_orders.audio_indexes.clone(),
params,
deep_orders.video_details.frame_rate,
deep_orders.audio_details.clone(),
)
}
}
Expand Down
23 changes: 13 additions & 10 deletions src/probe/dualmono_detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
OutputResult::{self, Entry},
ParameterValue,
},
probe::deep::{CheckName, CheckParameterValue, DualMonoResult, StreamProbeResult, VideoDetails},
probe::deep::{AudioDetails, CheckName, CheckParameterValue, DualMonoResult, StreamProbeResult},
};
use std::collections::{BTreeMap, HashMap};

Expand Down Expand Up @@ -134,7 +134,8 @@ pub fn detect_dualmono<S: ::std::hash::BuildHasher>(
streams: &mut [StreamProbeResult],
audio_indexes: Vec<u32>,
params: HashMap<String, CheckParameterValue, S>,
video_details: VideoDetails,
frame_duration: f32,
audio_details: Vec<AudioDetails>,
) {
for index in audio_indexes.clone() {
streams[index as usize].detected_dualmono = Some(vec![]);
Expand Down Expand Up @@ -164,14 +165,18 @@ pub fn detect_dualmono<S: ::std::hash::BuildHasher>(
None => warn!("No input message for the dualmono analysis (list of indexes to merge)"),
}

let end_from_duration = (((results.len() as f64 / audio_stream_qualif_number as f64) - 1.0)
/ video_details.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") {
let index: i32 = stream_id.parse().unwrap();
let audio_stream_details = audio_details.iter().find(|d| d.stream_index == index);
let end_from_duration = (((results.len() as f64 / audio_stream_qualif_number as f64) - 1.0)
/ (audio_stream_details.map(|d| d.sample_rate).unwrap_or(1) as f64
/ audio_stream_details
.map(|d| d.samples_per_frame)
.unwrap_or(1) as f64)
* 1000.0)
.round() as i64;
if streams[(index) as usize].detected_dualmono.is_none() {
error!("Error : unexpected detection on stream ${index}");
break;
Expand All @@ -191,8 +196,7 @@ pub fn detect_dualmono<S: ::std::hash::BuildHasher>(
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::<f64>().unwrap() - video_details.frame_duration as f64) * 1000.0)
.round() as i64;
((value.parse::<f64>().unwrap() - frame_duration as f64) * 1000.0).round() as i64;
}
}
if let Some(value) = entry_map.get("lavfi.aphasemeter.mono_duration") {
Expand All @@ -212,8 +216,7 @@ pub fn detect_dualmono<S: ::std::hash::BuildHasher>(
.as_mut()
.unwrap();
if let Some(last_detect) = detected_dualmono.last() {
let duration = last_detect.end - last_detect.start
+ (video_details.frame_duration * 1000.0).round() as i64;
let duration = last_detect.end - last_detect.start + (frame_duration * 1000.0).round() as i64;
if let Some(max) = max_duration {
if duration > max as i64 {
detected_dualmono.pop();
Expand Down
8 changes: 5 additions & 3 deletions src/probe/loudness_detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::order::{
ParameterValue,
};
use crate::probe::deep::{
CheckName, CheckParameterValue, LoudnessResult, MinMax, StreamProbeResult, VideoDetails,
AudioDetails, CheckName, CheckParameterValue, LoudnessResult, MinMax, StreamProbeResult,
};
use ffmpeg_sys_next::log10;
use std::collections::{BTreeMap, HashMap};
Expand Down Expand Up @@ -132,7 +132,7 @@ pub fn detect_loudness<S: ::std::hash::BuildHasher>(
streams: &mut [StreamProbeResult],
audio_indexes: Vec<u32>,
params: HashMap<String, CheckParameterValue, S>,
video_details: VideoDetails,
audio_details: Vec<AudioDetails>,
) {
for index in audio_indexes.clone() {
streams[index as usize].detected_loudness = Some(LoudnessResult {
Expand Down Expand Up @@ -169,7 +169,9 @@ pub fn detect_loudness<S: ::std::hash::BuildHasher>(
let mut channel_end = 0;
let mut pts_time: f32 = 0.0;
if let Some(pts) = entry_map.get("pts") {
pts_time = pts.parse::<f32>().unwrap() / video_details.sample_rate as f32;
let audio_stream_details = audio_details.iter().find(|d| d.stream_index == index);
pts_time = pts.parse::<f32>().unwrap()
/ audio_stream_details.map(|d| d.sample_rate).unwrap_or(1) as f32;
}

if let Some(value) = entry_map.get("lavfi.r128.I") {
Expand Down
39 changes: 28 additions & 11 deletions src/probe/silence_detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::order::{
OutputResult::Entry, ParameterValue,
};
use crate::probe::deep::{
CheckName, CheckParameterValue, SilenceResult, StreamProbeResult, VideoDetails,
AudioDetails, CheckName, CheckParameterValue, SilenceResult, StreamProbeResult,
};
use std::collections::{BTreeMap, HashMap};

Expand Down Expand Up @@ -97,7 +97,8 @@ pub fn detect_silence<S: ::std::hash::BuildHasher>(
streams: &mut [StreamProbeResult],
audio_indexes: Vec<u32>,
params: HashMap<String, CheckParameterValue, S>,
video_details: VideoDetails,
frame_duration: f32,
audio_details: Vec<AudioDetails>,
) {
for index in audio_indexes.clone() {
streams[index as usize].detected_silence = Some(vec![]);
Expand All @@ -106,10 +107,6 @@ pub fn detect_silence<S: ::std::hash::BuildHasher>(
info!("END OF SILENCE PROCESS");
info!("-> {:?} frames processed", results.len());

let end_from_duration = (((results.len() as f64 / audio_indexes.len() as f64) - 1.0)
/ video_details.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;
Expand All @@ -119,6 +116,14 @@ pub fn detect_silence<S: ::std::hash::BuildHasher>(
if let Entry(entry_map) = result {
if let Some(stream_id) = entry_map.get("stream_id") {
let index: i32 = stream_id.parse().unwrap();
let audio_stream_details = audio_details.iter().find(|d| d.stream_index == index);
let end_from_duration = (((results.len() as f64 / audio_indexes.len() as f64) - 1.0)
/ (audio_stream_details.map(|d| d.sample_rate).unwrap_or(1) as f64
/ audio_stream_details
.map(|d| d.samples_per_frame)
.unwrap_or(1) as f64)
* 1000.0)
.round() as i64;
if streams[(index) as usize].detected_silence.is_none() {
error!("Error : unexpected detection on stream ${index}");
break;
Expand All @@ -136,8 +141,7 @@ pub fn detect_silence<S: ::std::hash::BuildHasher>(
if let Some(value) = entry_map.get("lavfi.silence_end") {
if let Some(last_detect) = detected_silence.last_mut() {
last_detect.end =
((value.parse::<f64>().unwrap() - video_details.frame_duration as f64) * 1000.0)
.round() as i64;
((value.parse::<f64>().unwrap() - frame_duration as f64) * 1000.0).round() as i64;
}
}
if let Some(value) = entry_map.get("lavfi.silence_duration") {
Expand All @@ -150,8 +154,21 @@ pub fn detect_silence<S: ::std::hash::BuildHasher>(
}
}
}
for index in audio_indexes {
for index in audio_indexes.clone() {
let detected_silence = streams[(index) as usize].detected_silence.as_mut().unwrap();
let audio_stream_details = audio_details
.iter()
.find(|d| d.stream_index == index as i32);
let end_from_duration = match audio_stream_details.and_then(|d| d.stream_duration) {
Some(duration) => ((duration - frame_duration) * 1000.0).round() as i64,
None => (((results.len() as f64 / audio_indexes.len() as f64) - 1.0)
/ (audio_stream_details.map(|d| d.sample_rate).unwrap_or(1) as f64
/ audio_stream_details
.map(|d| d.samples_per_frame)
.unwrap_or(1) as f64)
* 1000.0)
.round() as i64,
};
if detected_silence.len() == 1
&& detected_silence[0].start == 0
&& detected_silence[0].end == end_from_duration
Expand All @@ -160,8 +177,8 @@ pub fn detect_silence<S: ::std::hash::BuildHasher>(
}
if let Some(max) = max_duration {
if let Some(last_detect) = detected_silence.last() {
let silence_duration = last_detect.end - last_detect.start
+ (video_details.frame_duration * 1000.0).round() as i64;
let silence_duration =
last_detect.end - last_detect.start + (frame_duration * 1000.0).round() as i64;
if silence_duration > max as i64 {
detected_silence.pop();
}
Expand Down
Loading

0 comments on commit 17fc78a

Please sign in to comment.