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