From 045292a34f4b57e1a93d58afcf2f4ef384759fc9 Mon Sep 17 00:00:00 2001 From: Martial Brasselet Date: Tue, 15 Oct 2024 17:49:43 +0200 Subject: [PATCH] manually call drop function --- src/audio_decoder.rs | 4 +++ src/audio_encoder.rs | 4 +++ src/filter_graph.rs | 7 +++++ src/format_context.rs | 5 ++++ src/order/decoder_format.rs | 28 ++++++++++++++++++ src/order/encoder_format.rs | 17 +++++++++++ src/order/mod.rs | 59 ++++++++++++++++++++++++++++++++++--- src/probe/deep.rs | 10 ++++++- src/probe/sine_detect.rs | 8 +---- src/subtitle_decoder.rs | 4 +++ src/video_decoder.rs | 6 ++++ src/video_encoder.rs | 4 +++ 12 files changed, 144 insertions(+), 12 deletions(-) diff --git a/src/audio_decoder.rs b/src/audio_decoder.rs index b28268d..31b4f28 100644 --- a/src/audio_decoder.rs +++ b/src/audio_decoder.rs @@ -76,6 +76,10 @@ impl AudioDecoder { }) } } + + pub fn close(&mut self) { + unsafe { avcodec_free_context(&mut self.codec_context) }; + } } impl Drop for AudioDecoder { diff --git a/src/audio_encoder.rs b/src/audio_encoder.rs index 0808c19..7a98383 100644 --- a/src/audio_encoder.rs +++ b/src/audio_encoder.rs @@ -98,6 +98,10 @@ impl AudioEncoder { } } } + + pub fn close(&mut self) { + unsafe { avcodec_free_context(&mut self.codec_context) }; + } } impl Drop for AudioEncoder { diff --git a/src/filter_graph.rs b/src/filter_graph.rs index 03c9f9b..6b4a14b 100644 --- a/src/filter_graph.rs +++ b/src/filter_graph.rs @@ -308,6 +308,13 @@ impl FilterGraph { Ok((output_audio_frames, output_video_frames)) } + + pub fn close(&mut self) -> Result<(), String> { + if !self.graph.is_null() { + unsafe { avfilter_graph_free(&mut self.graph) }; + } + Ok(()) + } } impl Drop for FilterGraph { diff --git a/src/format_context.rs b/src/format_context.rs index f3e0fc1..1aea984 100644 --- a/src/format_context.rs +++ b/src/format_context.rs @@ -79,6 +79,11 @@ impl FormatContext { Ok(()) } + pub fn close_output(&self) -> Result<(), String> { + unsafe { avformat_free_context(self.format_context) }; + Ok(()) + } + pub fn add_video_stream(&mut self, encoder: &VideoEncoder) -> Result<(), String> { unsafe { let av_stream = avformat_new_stream(self.format_context, null_mut()); diff --git a/src/order/decoder_format.rs b/src/order/decoder_format.rs index c8011be..fc41669 100644 --- a/src/order/decoder_format.rs +++ b/src/order/decoder_format.rs @@ -96,4 +96,32 @@ impl DecoderFormat { } } } + + pub fn close(&mut self, input: &Input) { + match input { + Input::VideoFrames { .. } => {} + Input::Streams { streams, .. } => { + for stream in streams { + match self.context.get_stream_type(stream.index as isize) { + AVMediaType::AVMEDIA_TYPE_VIDEO => { + for video_decoder in &mut self.video_decoders { + video_decoder.close(); + } + } + AVMediaType::AVMEDIA_TYPE_AUDIO => { + for audio_decoder in &mut self.audio_decoders { + audio_decoder.close(); + } + } + AVMediaType::AVMEDIA_TYPE_SUBTITLE => { + for subtitle_decoder in &mut self.subtitle_decoders { + subtitle_decoder.close(); + } + } + _ => {} + } + } + } + } + } } diff --git a/src/order/encoder_format.rs b/src/order/encoder_format.rs index 374af98..a3d3531 100644 --- a/src/order/encoder_format.rs +++ b/src/order/encoder_format.rs @@ -168,4 +168,21 @@ impl EncoderFormat { Ok(r_packet) } + + pub fn close(&mut self, output: &Output) { + match output.kind { + Some(OutputKind::File) | Some(OutputKind::Packet) => {} + Some(OutputKind::AudioMetadata) => { + for audio_encoder in &mut self.audio_encoders { + audio_encoder.close(); + } + } + Some(OutputKind::VideoMetadata) => { + for video_encoder in &mut self.video_encoders { + video_encoder.close(); + } + } + None => {} + } + } } diff --git a/src/order/mod.rs b/src/order/mod.rs index 194f230..78c0ad0 100644 --- a/src/order/mod.rs +++ b/src/order/mod.rs @@ -1,3 +1,5 @@ +use ffmpeg_sys_next::{av_frame_free, av_packet_free}; + use crate::filter_graph::FilterGraph; use std::collections::HashMap; @@ -75,12 +77,24 @@ impl Order { Ok(()) } + pub fn close(&mut self) -> Result<(), String> { + warn!("Close inputs"); + self.close_input_format()?; + warn!("Close outputs"); + self.close_output_format()?; + warn!("Close graph"); + self.close_graph()?; + + Ok(()) + } + pub fn process(&mut self) -> Result, String> { let mut results: Vec = vec![]; let mut decode_end = false; while !decode_end { - let (in_audio_frames, in_video_frames, in_subtitle_packets, end) = self.process_input(); + let (mut in_audio_frames, mut in_video_frames, mut in_subtitle_packets, end) = + self.process_input(); if end == self.total_streams { decode_end = true; } @@ -93,6 +107,16 @@ impl Order { error!("Error while filtering : {msg}"); } } + + for frame in &mut in_audio_frames { + unsafe { av_frame_free(&mut frame.frame) }; + } + for frame in &mut in_video_frames { + unsafe { av_frame_free(&mut frame.frame) }; + } + for packet in &mut in_subtitle_packets { + unsafe { av_packet_free(&mut packet.packet) }; + } } Ok(results) @@ -162,10 +186,10 @@ impl Order { ) -> Result, String> { let mut results = vec![]; - let (output_audio_frames, output_video_frames) = self + let (mut output_audio_frames, mut output_video_frames) = self .filter_graph .process(in_audio_frames, in_video_frames)?; - for output_frame in output_audio_frames { + for output_frame in &mut output_audio_frames { for output in &self.outputs { if output.stream == output_frame.name { if let Some(OutputKind::AudioMetadata) = output.kind { @@ -191,13 +215,14 @@ impl Order { results.push(OutputResult::Packet(packet)); }; } + unsafe { av_frame_free(&mut output_frame.frame) }; } for output_packet in in_subtitle_packets { for output in &mut self.output_formats { output.wrap(output_packet)?; } } - for output_frame in output_video_frames { + for output_frame in &mut output_video_frames { for output in &self.outputs { if let Some(OutputKind::VideoMetadata) = output.kind { let mut entry = HashMap::new(); @@ -218,6 +243,7 @@ impl Order { results.push(OutputResult::Packet(packet)); }; } + unsafe { av_frame_free(&mut output_frame.frame) }; } Ok(results) @@ -314,6 +340,31 @@ impl Order { Ok(filters) } + + pub fn close_input_format(&mut self) -> Result<(), String> { + for input_format in &mut self.input_formats { + for input in &self.inputs { + input_format.close(input); + } + input_format.context.close_input(); + } + Ok(()) + } + + fn close_output_format(&mut self) -> Result<(), String> { + for output_format in &mut self.output_formats { + for output in &self.outputs { + output_format.close(output); + } + output_format.context.close_input(); + } + Ok(()) + } + + pub fn close_graph(&mut self) -> Result<(), String> { + self.filter_graph.close()?; + Ok(()) + } } #[test] diff --git a/src/probe/deep.rs b/src/probe/deep.rs index 7a9f8c4..edb8cc5 100644 --- a/src/probe/deep.rs +++ b/src/probe/deep.rs @@ -681,8 +681,8 @@ impl DeepProbe { CheckName::Tone => { if let Some(params) = deep_orders.check.sine_detect.clone() { detect_sine( + context, &deep_orders.output_results, - &self.filename, &mut deep_orders.streams, deep_orders.audio_indexes.clone(), params, @@ -770,6 +770,9 @@ impl DeepProbe { for mut frame in in_video_frames { unsafe { av_frame_free(&mut frame.frame) }; } + for mut packet in in_subtitle_packets { + unsafe { av_packet_free(&mut packet.packet) }; + } } if let Err(msg) = self.get_results(&context, &mut deep_orders) { @@ -784,7 +787,12 @@ impl DeepProbe { format, }); + for order in &mut deep_orders.orders { + let _ = order.1.close(); + } + let _ = order_src.close(); context.close_input(); + Ok(()) } } diff --git a/src/probe/sine_detect.rs b/src/probe/sine_detect.rs index fb8738e..38eacc9 100644 --- a/src/probe/sine_detect.rs +++ b/src/probe/sine_detect.rs @@ -105,8 +105,8 @@ pub fn create_graph( } pub fn detect_sine( + context: &FormatContext, output_results: &BTreeMap>, - filename: &str, streams: &mut [StreamProbeResult], audio_indexes: Vec, params: HashMap, @@ -141,12 +141,6 @@ pub fn detect_sine( None => return warn!("No input message for the 1000Hz analysis (audio qualification)"), } - 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/subtitle_decoder.rs b/src/subtitle_decoder.rs index 70d0c8a..4c12abb 100644 --- a/src/subtitle_decoder.rs +++ b/src/subtitle_decoder.rs @@ -35,6 +35,10 @@ impl SubtitleDecoder { }) } } + + pub fn close(&mut self) { + unsafe { avcodec_free_context(&mut self.codec_context) }; + } } impl Drop for SubtitleDecoder { diff --git a/src/video_decoder.rs b/src/video_decoder.rs index 07fe56e..5327c36 100644 --- a/src/video_decoder.rs +++ b/src/video_decoder.rs @@ -134,6 +134,12 @@ impl VideoDecoder { }) } } + + pub fn close(&mut self) { + if !self.codec_context.is_null() { + unsafe { avcodec_free_context(&mut self.codec_context) }; + } + } } impl Drop for VideoDecoder { diff --git a/src/video_encoder.rs b/src/video_encoder.rs index 258a244..a4e2764 100644 --- a/src/video_encoder.rs +++ b/src/video_encoder.rs @@ -148,6 +148,10 @@ impl VideoEncoder { Ok(true) } } + + pub fn close(&mut self) { + unsafe { avcodec_free_context(&mut self.codec_context) }; + } } impl Drop for VideoEncoder {