pub struct Graph { /* private fields */ }Implementations§
Source§impl Graph
impl Graph
pub unsafe fn wrap(ptr: *mut AVFilterGraph) -> Self
pub unsafe fn as_ptr(&self) -> *const AVFilterGraph
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFilterGraph
Source§impl Graph
impl Graph
Sourcepub fn new() -> Self
pub fn new() -> Self
Examples found in repository?
examples/transcode-audio.rs (line 14)
9fn filter(
10 spec: &str,
11 decoder: &codec::decoder::Audio,
12 encoder: &codec::encoder::Audio,
13) -> Result<filter::Graph, ffmpeg::Error> {
14 let mut filter = filter::Graph::new();
15
16 let args = format!(
17 "time_base={}:sample_rate={}:sample_fmt={}:channel_layout=0x{:x}",
18 decoder.time_base(),
19 decoder.rate(),
20 decoder.format().name(),
21 decoder.channel_layout().bits()
22 );
23
24 filter.add(&filter::find("abuffer").unwrap(), "in", &args)?;
25 filter.add(&filter::find("abuffersink").unwrap(), "out", "")?;
26
27 {
28 let mut out = filter.get("out").unwrap();
29
30 out.set_sample_format(encoder.format());
31 out.set_channel_layout(encoder.channel_layout());
32 out.set_sample_rate(encoder.rate());
33 }
34
35 filter.output("in", 0)?.input("out", 0)?.parse(spec)?;
36 filter.validate()?;
37
38 println!("{}", filter.dump());
39
40 if let Some(codec) = encoder.codec() {
41 if !codec
42 .capabilities()
43 .contains(ffmpeg::codec::capabilities::Capabilities::VARIABLE_FRAME_SIZE)
44 {
45 filter
46 .get("out")
47 .unwrap()
48 .sink()
49 .set_frame_size(encoder.frame_size());
50 }
51 }
52
53 Ok(filter)
54}Sourcepub fn validate(&mut self) -> Result<(), Error>
pub fn validate(&mut self) -> Result<(), Error>
Examples found in repository?
examples/transcode-audio.rs (line 36)
9fn filter(
10 spec: &str,
11 decoder: &codec::decoder::Audio,
12 encoder: &codec::encoder::Audio,
13) -> Result<filter::Graph, ffmpeg::Error> {
14 let mut filter = filter::Graph::new();
15
16 let args = format!(
17 "time_base={}:sample_rate={}:sample_fmt={}:channel_layout=0x{:x}",
18 decoder.time_base(),
19 decoder.rate(),
20 decoder.format().name(),
21 decoder.channel_layout().bits()
22 );
23
24 filter.add(&filter::find("abuffer").unwrap(), "in", &args)?;
25 filter.add(&filter::find("abuffersink").unwrap(), "out", "")?;
26
27 {
28 let mut out = filter.get("out").unwrap();
29
30 out.set_sample_format(encoder.format());
31 out.set_channel_layout(encoder.channel_layout());
32 out.set_sample_rate(encoder.rate());
33 }
34
35 filter.output("in", 0)?.input("out", 0)?.parse(spec)?;
36 filter.validate()?;
37
38 println!("{}", filter.dump());
39
40 if let Some(codec) = encoder.codec() {
41 if !codec
42 .capabilities()
43 .contains(ffmpeg::codec::capabilities::Capabilities::VARIABLE_FRAME_SIZE)
44 {
45 filter
46 .get("out")
47 .unwrap()
48 .sink()
49 .set_frame_size(encoder.frame_size());
50 }
51 }
52
53 Ok(filter)
54}Sourcepub fn add(
&mut self,
filter: &Filter,
name: &str,
args: &str,
) -> Result<Context, Error>
pub fn add( &mut self, filter: &Filter, name: &str, args: &str, ) -> Result<Context, Error>
Examples found in repository?
examples/transcode-audio.rs (line 24)
9fn filter(
10 spec: &str,
11 decoder: &codec::decoder::Audio,
12 encoder: &codec::encoder::Audio,
13) -> Result<filter::Graph, ffmpeg::Error> {
14 let mut filter = filter::Graph::new();
15
16 let args = format!(
17 "time_base={}:sample_rate={}:sample_fmt={}:channel_layout=0x{:x}",
18 decoder.time_base(),
19 decoder.rate(),
20 decoder.format().name(),
21 decoder.channel_layout().bits()
22 );
23
24 filter.add(&filter::find("abuffer").unwrap(), "in", &args)?;
25 filter.add(&filter::find("abuffersink").unwrap(), "out", "")?;
26
27 {
28 let mut out = filter.get("out").unwrap();
29
30 out.set_sample_format(encoder.format());
31 out.set_channel_layout(encoder.channel_layout());
32 out.set_sample_rate(encoder.rate());
33 }
34
35 filter.output("in", 0)?.input("out", 0)?.parse(spec)?;
36 filter.validate()?;
37
38 println!("{}", filter.dump());
39
40 if let Some(codec) = encoder.codec() {
41 if !codec
42 .capabilities()
43 .contains(ffmpeg::codec::capabilities::Capabilities::VARIABLE_FRAME_SIZE)
44 {
45 filter
46 .get("out")
47 .unwrap()
48 .sink()
49 .set_frame_size(encoder.frame_size());
50 }
51 }
52
53 Ok(filter)
54}Sourcepub fn get(&mut self, name: &str) -> Option<Context>
pub fn get(&mut self, name: &str) -> Option<Context>
Examples found in repository?
examples/transcode-audio.rs (line 28)
9fn filter(
10 spec: &str,
11 decoder: &codec::decoder::Audio,
12 encoder: &codec::encoder::Audio,
13) -> Result<filter::Graph, ffmpeg::Error> {
14 let mut filter = filter::Graph::new();
15
16 let args = format!(
17 "time_base={}:sample_rate={}:sample_fmt={}:channel_layout=0x{:x}",
18 decoder.time_base(),
19 decoder.rate(),
20 decoder.format().name(),
21 decoder.channel_layout().bits()
22 );
23
24 filter.add(&filter::find("abuffer").unwrap(), "in", &args)?;
25 filter.add(&filter::find("abuffersink").unwrap(), "out", "")?;
26
27 {
28 let mut out = filter.get("out").unwrap();
29
30 out.set_sample_format(encoder.format());
31 out.set_channel_layout(encoder.channel_layout());
32 out.set_sample_rate(encoder.rate());
33 }
34
35 filter.output("in", 0)?.input("out", 0)?.parse(spec)?;
36 filter.validate()?;
37
38 println!("{}", filter.dump());
39
40 if let Some(codec) = encoder.codec() {
41 if !codec
42 .capabilities()
43 .contains(ffmpeg::codec::capabilities::Capabilities::VARIABLE_FRAME_SIZE)
44 {
45 filter
46 .get("out")
47 .unwrap()
48 .sink()
49 .set_frame_size(encoder.frame_size());
50 }
51 }
52
53 Ok(filter)
54}
55
56struct Transcoder {
57 stream: usize,
58 filter: filter::Graph,
59 decoder: codec::decoder::Audio,
60 encoder: codec::encoder::Audio,
61 in_time_base: ffmpeg::Rational,
62 out_time_base: ffmpeg::Rational,
63}
64
65fn transcoder<P: AsRef<Path> + ?Sized>(
66 ictx: &mut format::context::Input,
67 octx: &mut format::context::Output,
68 path: &P,
69 filter_spec: &str,
70) -> Result<Transcoder, ffmpeg::Error> {
71 let input = ictx
72 .streams()
73 .best(media::Type::Audio)
74 .expect("could not find best audio stream");
75 let context = ffmpeg::codec::context::Context::from_parameters(input.parameters())?;
76 let mut decoder = context.decoder().audio()?;
77 let codec = ffmpeg::encoder::find(octx.format().codec(path, media::Type::Audio))
78 .expect("failed to find encoder")
79 .audio()?;
80 let global = octx
81 .format()
82 .flags()
83 .contains(ffmpeg::format::flag::Flags::GLOBAL_HEADER);
84
85 decoder.set_parameters(input.parameters())?;
86
87 let mut output = octx.add_stream(codec)?;
88 let context = ffmpeg::codec::context::Context::from_parameters(output.parameters())?;
89 let mut encoder = context.encoder().audio()?;
90
91 let channel_layout = codec
92 .channel_layouts()
93 .map(|cls| cls.best(decoder.channel_layout().channels()))
94 .unwrap_or(ffmpeg::channel_layout::ChannelLayout::STEREO);
95
96 if global {
97 encoder.set_flags(ffmpeg::codec::flag::Flags::GLOBAL_HEADER);
98 }
99
100 encoder.set_rate(decoder.rate() as i32);
101 encoder.set_channel_layout(channel_layout);
102 #[cfg(not(feature = "ffmpeg_7_0"))]
103 {
104 encoder.set_channels(channel_layout.channels());
105 }
106 encoder.set_format(
107 codec
108 .formats()
109 .expect("unknown supported formats")
110 .next()
111 .unwrap(),
112 );
113 encoder.set_bit_rate(decoder.bit_rate());
114 encoder.set_max_bit_rate(decoder.max_bit_rate());
115
116 encoder.set_time_base((1, decoder.rate() as i32));
117 output.set_time_base((1, decoder.rate() as i32));
118
119 let encoder = encoder.open_as(codec)?;
120 output.set_parameters(&encoder);
121
122 let filter = filter(filter_spec, &decoder, &encoder)?;
123
124 let in_time_base = decoder.time_base();
125 let out_time_base = output.time_base();
126
127 Ok(Transcoder {
128 stream: input.index(),
129 filter,
130 decoder,
131 encoder,
132 in_time_base,
133 out_time_base,
134 })
135}
136
137impl Transcoder {
138 fn send_frame_to_encoder(&mut self, frame: &ffmpeg::Frame) {
139 self.encoder.send_frame(frame).unwrap();
140 }
141
142 fn send_eof_to_encoder(&mut self) {
143 self.encoder.send_eof().unwrap();
144 }
145
146 fn receive_and_process_encoded_packets(&mut self, octx: &mut format::context::Output) {
147 let mut encoded = ffmpeg::Packet::empty();
148 while self.encoder.receive_packet(&mut encoded).is_ok() {
149 encoded.set_stream(0);
150 encoded.rescale_ts(self.in_time_base, self.out_time_base);
151 encoded.write_interleaved(octx).unwrap();
152 }
153 }
154
155 fn add_frame_to_filter(&mut self, frame: &ffmpeg::Frame) {
156 self.filter.get("in").unwrap().source().add(frame).unwrap();
157 }
158
159 fn flush_filter(&mut self) {
160 self.filter.get("in").unwrap().source().flush().unwrap();
161 }
162
163 fn get_and_process_filtered_frames(&mut self, octx: &mut format::context::Output) {
164 let mut filtered = frame::Audio::empty();
165 while self
166 .filter
167 .get("out")
168 .unwrap()
169 .sink()
170 .frame(&mut filtered)
171 .is_ok()
172 {
173 self.send_frame_to_encoder(&filtered);
174 self.receive_and_process_encoded_packets(octx);
175 }
176 }Sourcepub fn dump(&self) -> String
pub fn dump(&self) -> String
Examples found in repository?
examples/transcode-audio.rs (line 38)
9fn filter(
10 spec: &str,
11 decoder: &codec::decoder::Audio,
12 encoder: &codec::encoder::Audio,
13) -> Result<filter::Graph, ffmpeg::Error> {
14 let mut filter = filter::Graph::new();
15
16 let args = format!(
17 "time_base={}:sample_rate={}:sample_fmt={}:channel_layout=0x{:x}",
18 decoder.time_base(),
19 decoder.rate(),
20 decoder.format().name(),
21 decoder.channel_layout().bits()
22 );
23
24 filter.add(&filter::find("abuffer").unwrap(), "in", &args)?;
25 filter.add(&filter::find("abuffersink").unwrap(), "out", "")?;
26
27 {
28 let mut out = filter.get("out").unwrap();
29
30 out.set_sample_format(encoder.format());
31 out.set_channel_layout(encoder.channel_layout());
32 out.set_sample_rate(encoder.rate());
33 }
34
35 filter.output("in", 0)?.input("out", 0)?.parse(spec)?;
36 filter.validate()?;
37
38 println!("{}", filter.dump());
39
40 if let Some(codec) = encoder.codec() {
41 if !codec
42 .capabilities()
43 .contains(ffmpeg::codec::capabilities::Capabilities::VARIABLE_FRAME_SIZE)
44 {
45 filter
46 .get("out")
47 .unwrap()
48 .sink()
49 .set_frame_size(encoder.frame_size());
50 }
51 }
52
53 Ok(filter)
54}pub fn input(&mut self, name: &str, pad: usize) -> Result<Parser<'_>, Error>
Sourcepub fn output(&mut self, name: &str, pad: usize) -> Result<Parser<'_>, Error>
pub fn output(&mut self, name: &str, pad: usize) -> Result<Parser<'_>, Error>
Examples found in repository?
examples/transcode-audio.rs (line 35)
9fn filter(
10 spec: &str,
11 decoder: &codec::decoder::Audio,
12 encoder: &codec::encoder::Audio,
13) -> Result<filter::Graph, ffmpeg::Error> {
14 let mut filter = filter::Graph::new();
15
16 let args = format!(
17 "time_base={}:sample_rate={}:sample_fmt={}:channel_layout=0x{:x}",
18 decoder.time_base(),
19 decoder.rate(),
20 decoder.format().name(),
21 decoder.channel_layout().bits()
22 );
23
24 filter.add(&filter::find("abuffer").unwrap(), "in", &args)?;
25 filter.add(&filter::find("abuffersink").unwrap(), "out", "")?;
26
27 {
28 let mut out = filter.get("out").unwrap();
29
30 out.set_sample_format(encoder.format());
31 out.set_channel_layout(encoder.channel_layout());
32 out.set_sample_rate(encoder.rate());
33 }
34
35 filter.output("in", 0)?.input("out", 0)?.parse(spec)?;
36 filter.validate()?;
37
38 println!("{}", filter.dump());
39
40 if let Some(codec) = encoder.codec() {
41 if !codec
42 .capabilities()
43 .contains(ffmpeg::codec::capabilities::Capabilities::VARIABLE_FRAME_SIZE)
44 {
45 filter
46 .get("out")
47 .unwrap()
48 .sink()
49 .set_frame_size(encoder.frame_size());
50 }
51 }
52
53 Ok(filter)
54}pub fn parse(&mut self, spec: &str) -> Result<(), Error>
Trait Implementations§
impl Send for Graph
impl Sync for Graph
Auto Trait Implementations§
impl Freeze for Graph
impl RefUnwindSafe for Graph
impl Unpin for Graph
impl UnsafeUnpin for Graph
impl UnwindSafe for Graph
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more