From fd7456f3ff75bcd24d97b86593203064c52df082 Mon Sep 17 00:00:00 2001 From: Evy Garden Date: Sat, 6 Jan 2024 13:56:22 +0100 Subject: [PATCH 1/9] initial builder with reader_options --- src/decode.rs | 37 +++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/decode.rs b/src/decode.rs index 3ad3733..c203e69 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -19,6 +19,43 @@ use crate::{ffi::convert_frame_to_ndarray_rgb24, Frame, Time}; type Result = std::result::Result; +pub struct DecoderBuilder<'a> { + source: Locator, + reader_stream_index: Option, + reader_options: Option>, +} + +impl<'a> DecoderBuilder<'a> { + pub fn new(source: &Locator) -> Result { + Ok(Self { + source: source.clone(), + reader_stream_index: None, + reader_options: None, + }) + } + + pub fn build(self) -> Result { + let reader = match self.reader_options { + Some(options) => Reader::new_with_options(&self.source, &options)?, + None => Reader::new(&self.source)?, + }; + let reader_stream_index = match self.reader_stream_index { + Some(index) => index, + None => reader.best_video_stream_index()?, + }; + + Ok(Decoder { + decoder: DecoderSplit::new(&reader, reader_stream_index, None)?, + reader, + reader_stream_index, + }) + } + + pub fn reader_options(&mut self, options: Options<'a>) { + self.reader_options = Some(options) + } +} + /// Decode video files and streams. /// /// # Example diff --git a/src/lib.rs b/src/lib.rs index 46aed92..ac49766 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,7 @@ mod rtp; mod stream; mod time; -pub use decode::{Decoder, DecoderSplit}; +pub use decode::{Decoder, DecoderBuilder, DecoderSplit}; pub use encode::{Encoder, Settings as EncoderSettings}; pub use error::Error; pub use extradata::{Pps, Sps}; From 9b13d6ab75206be9b1230939938be74c5091182f Mon Sep 17 00:00:00 2001 From: Evy Garden Date: Sat, 6 Jan 2024 14:10:43 +0100 Subject: [PATCH 2/9] remove result and return mut self ref --- src/decode.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/decode.rs b/src/decode.rs index c203e69..a691648 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -26,12 +26,12 @@ pub struct DecoderBuilder<'a> { } impl<'a> DecoderBuilder<'a> { - pub fn new(source: &Locator) -> Result { - Ok(Self { + pub fn new(source: &Locator) -> Self { + Self { source: source.clone(), reader_stream_index: None, reader_options: None, - }) + } } pub fn build(self) -> Result { @@ -51,8 +51,9 @@ impl<'a> DecoderBuilder<'a> { }) } - pub fn reader_options(&mut self, options: Options<'a>) { - self.reader_options = Some(options) + pub fn reader_options(&mut self, options: Options<'a>) -> &mut Self { + self.reader_options = Some(options); + self } } From 5ad63d2235ac506a662b69e7fcfcf29501ca1c41 Mon Sep 17 00:00:00 2001 From: Evy Garden Date: Sat, 6 Jan 2024 14:14:13 +0100 Subject: [PATCH 3/9] don't use references --- src/decode.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/decode.rs b/src/decode.rs index a691648..9aaf345 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -51,7 +51,7 @@ impl<'a> DecoderBuilder<'a> { }) } - pub fn reader_options(&mut self, options: Options<'a>) -> &mut Self { + pub fn reader_options(mut self, options: Options<'a>) -> Self { self.reader_options = Some(options); self } From 865feccba1e737c554caa71ecb83da441f7b4024 Mon Sep 17 00:00:00 2001 From: Evy Garden Date: Sat, 6 Jan 2024 14:31:44 +0100 Subject: [PATCH 4/9] add resize to builder --- src/decode.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/decode.rs b/src/decode.rs index 9aaf345..ebdcba6 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -23,6 +23,7 @@ pub struct DecoderBuilder<'a> { source: Locator, reader_stream_index: Option, reader_options: Option>, + resize: Option, } impl<'a> DecoderBuilder<'a> { @@ -31,6 +32,7 @@ impl<'a> DecoderBuilder<'a> { source: source.clone(), reader_stream_index: None, reader_options: None, + resize: None, } } @@ -45,7 +47,7 @@ impl<'a> DecoderBuilder<'a> { }; Ok(Decoder { - decoder: DecoderSplit::new(&reader, reader_stream_index, None)?, + decoder: DecoderSplit::new(&reader, reader_stream_index, self.resize)?, reader, reader_stream_index, }) @@ -55,6 +57,11 @@ impl<'a> DecoderBuilder<'a> { self.reader_options = Some(options); self } + + pub fn resize(mut self, resize: Resize) -> Self { + self.resize = Some(resize); + self + } } /// Decode video files and streams. From ccda1639e57da5d6507569eb7708d22a5f0ed11b Mon Sep 17 00:00:00 2001 From: Evy Garden Date: Sat, 6 Jan 2024 14:45:03 +0100 Subject: [PATCH 5/9] build reader at start --- src/decode.rs | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/src/decode.rs b/src/decode.rs index ebdcba6..1353e4f 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -12,52 +12,45 @@ use crate::frame::FRAME_PIXEL_FORMAT; use crate::io::Reader; use crate::options::Options; use crate::packet::Packet; -use crate::{Error, Locator, RawFrame, Resize}; +use crate::{Error, Locator, RawFrame, Resize, StreamInfo}; #[cfg(feature = "ndarray")] use crate::{ffi::convert_frame_to_ndarray_rgb24, Frame, Time}; type Result = std::result::Result; -pub struct DecoderBuilder<'a> { - source: Locator, +pub struct DecoderBuilder { + reader: Reader, reader_stream_index: Option, - reader_options: Option>, resize: Option, } -impl<'a> DecoderBuilder<'a> { - pub fn new(source: &Locator) -> Self { - Self { - source: source.clone(), +impl<'a> DecoderBuilder { + pub fn new(source: &Locator, reader_options: Option) -> Result { + let reader = match reader_options { + Some(options) => Reader::new_with_options(&source, &options)?, + None => Reader::new(&source)?, + }; + Ok(Self { + reader, reader_stream_index: None, - reader_options: None, resize: None, - } + }) } pub fn build(self) -> Result { - let reader = match self.reader_options { - Some(options) => Reader::new_with_options(&self.source, &options)?, - None => Reader::new(&self.source)?, - }; let reader_stream_index = match self.reader_stream_index { Some(index) => index, - None => reader.best_video_stream_index()?, + None => self.reader.best_video_stream_index()?, }; Ok(Decoder { - decoder: DecoderSplit::new(&reader, reader_stream_index, self.resize)?, - reader, + decoder: DecoderSplit::new(&self.reader, reader_stream_index, self.resize)?, + reader: self.reader, reader_stream_index, }) } - pub fn reader_options(mut self, options: Options<'a>) -> Self { - self.reader_options = Some(options); - self - } - pub fn resize(mut self, resize: Resize) -> Self { self.resize = Some(resize); self From 10374b1c8a83a4267d094eac2e22ab8a5596a35b Mon Sep 17 00:00:00 2001 From: Evy Garden Date: Sat, 6 Jan 2024 14:53:15 +0100 Subject: [PATCH 6/9] make stream_info public --- src/stream.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stream.rs b/src/stream.rs index bc7c576..3db02c3 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -12,8 +12,8 @@ type Result = std::result::Result; #[derive(Clone)] pub struct StreamInfo { pub index: usize, - codec_parameters: AvCodecParameters, - time_base: AvRational, + pub codec_parameters: AvCodecParameters, + pub time_base: AvRational, } impl StreamInfo { From 318071c8b5b5bb56ef42f1c2d17ed8aaf64818af Mon Sep 17 00:00:00 2001 From: Evy Garden Date: Sat, 6 Jan 2024 14:54:16 +0100 Subject: [PATCH 7/9] add stream index selector --- src/decode.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/decode.rs b/src/decode.rs index 1353e4f..5eecd0d 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -55,6 +55,25 @@ impl<'a> DecoderBuilder { self.resize = Some(resize); self } + + pub fn reader_stream_index(mut self, selector: SelectorFn) -> Result + where + SelectorFn: FnOnce(Vec) -> usize, + { + let stream_infos = self + .reader + .input + .streams() + .enumerate() + .map(|(index, stream)| StreamInfo { + index, + codec_parameters: stream.parameters(), + time_base: stream.time_base(), + }) + .collect(); + self.reader_stream_index = Some(selector(stream_infos)); + Ok(self) + } } /// Decode video files and streams. From 48d59935e4ed8ddeb3011a4b6bdcf82fe3dd1f38 Mon Sep 17 00:00:00 2001 From: Evy Garden Date: Sat, 6 Jan 2024 14:55:38 +0100 Subject: [PATCH 8/9] remove unnecessary result --- src/decode.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/decode.rs b/src/decode.rs index 5eecd0d..e8323f7 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -56,7 +56,7 @@ impl<'a> DecoderBuilder { self } - pub fn reader_stream_index(mut self, selector: SelectorFn) -> Result + pub fn reader_stream_index(mut self, selector: SelectorFn) -> Self where SelectorFn: FnOnce(Vec) -> usize, { @@ -72,7 +72,7 @@ impl<'a> DecoderBuilder { }) .collect(); self.reader_stream_index = Some(selector(stream_infos)); - Ok(self) + self } } From 1ef9bc2c1b6c40847502d06ffbcec2de365df533 Mon Sep 17 00:00:00 2001 From: Evy Garden Date: Sat, 6 Jan 2024 14:57:53 +0100 Subject: [PATCH 9/9] remove new from decoder --- src/decode.rs | 64 --------------------------------------------------- 1 file changed, 64 deletions(-) diff --git a/src/decode.rs b/src/decode.rs index e8323f7..e4a19f3 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -95,70 +95,6 @@ pub struct Decoder { } impl Decoder { - /// Create a new decoder for the specified file. - /// - /// # Arguments - /// - /// * `source` - Locator to file to decode. - pub fn new(source: &Locator) -> Result { - let reader = Reader::new(source)?; - let reader_stream_index = reader.best_video_stream_index()?; - Ok(Self { - decoder: DecoderSplit::new(&reader, reader_stream_index, None)?, - reader, - reader_stream_index, - }) - } - - /// Create a new decoder for the specified file with input options. - /// - /// # Arguments - /// - /// * `source` - Locator to file to decode. - /// * `options` - The input options. - pub fn new_with_options(source: &Locator, options: &Options) -> Result { - let reader = Reader::new_with_options(source, options)?; - let reader_stream_index = reader.best_video_stream_index()?; - Ok(Self { - decoder: DecoderSplit::new(&reader, reader_stream_index, None)?, - reader, - reader_stream_index, - }) - } - - /// Create a new decoder for the specified file with input options and custom dimensions. Each - /// frame will be resized to the given dimensions. - /// - /// # Arguments - /// - /// * `source` - Locator to file to decode. - /// * `options` - The input options. - /// * `resize` - How to resize frames. - /// - /// # Example - /// - /// ```ignore - /// let decoder = Decoder::new_with_options_and_resize( - /// &PathBuf::from("video.mp4").into(), - /// Options::new_with_rtsp_transport_tcp(), - /// Resize::Exact(800, 600), - /// ) - /// .unwrap(); - /// ``` - pub fn new_with_options_and_resize( - source: &Locator, - options: &Options, - resize: Resize, - ) -> Result { - let reader = Reader::new_with_options(source, options)?; - let reader_stream_index = reader.best_video_stream_index()?; - Ok(Self { - decoder: DecoderSplit::new(&reader, reader_stream_index, Some(resize))?, - reader, - reader_stream_index, - }) - } - /// Get decoder time base. #[inline] pub fn time_base(&self) -> AvRational {